注意:问题底部有一个重大编辑 - 看看
问题
假设我有一组要点:
我想找到它周围点最多的点,在半径内(即圆形)或在二维点的半径内(即正方形)。我将其称为最密集点函数。
对于这个问题中的图表,我将周围区域表示为圆圈。在上图中,中间点的周围区域显示为绿色。这个中间点具有半径内所有点中最周围的点,并将由最密集的点函数返回。
我试过的
解决此问题的一种可行方法是使用范围搜索解决方案;这个答案进一步解释了它有“最坏情况时间”。使用它,我可以获得每个点周围的点数,并选择周围点数最多的点。
但是,如果这些点非常密集(大约一百万),那么:
那么这百万个点()中的每一个都需要执行范围搜索。对于以下点树类型,最坏情况时间(其中是范围内返回的点数)为真:
- 二维的 kd-trees(实际上稍微差一点,在 处),
- 二维范围的树,
- 四叉树,最坏情况时间为
因此,对于组内所有点的半径内的一组点,它给出了每个点的复杂度。这产生了超过一万亿次操作!
关于实现这一目标的更有效、更精确的方法的任何想法,以便我可以在合理的时间内(最好或更少)找到一组点周围点最多的点?
编辑
原来上面的方法是正确的!我只需要帮助实现它。
(半)解决方案
如果我使用二维范围树:
- 一个范围报告查询成本,对于返回的点,
- 对于具有分数级联的范围树(也称为分层范围树),复杂度为,
- 对于 2 维,即,
- 此外,如果我执行范围计数查询(即,我不报告每个点),那么它的成本为.
我会在每一点上执行这个 - 产生我想要的复杂性!
问题
但是,我无法弄清楚如何为二维分层范围树的计数查询编写代码。
我找到了关于范围树的一个很好的资源(从第 113 页开始),包括二维范围树伪代码。但是我不知道如何引入分数级联,也不知道如何正确实现计数查询,因此它很O(log n)
复杂。
我还在这里和这里在 Java 中找到了两个范围树实现,在 C++ 中找到了一个,尽管我不确定这是否使用分数级联,因为它在countInRange
方法上方指出
它返回最坏情况下此类点的数量 * O(log(n)^d) 时间。它还可以在最坏的情况下返回矩形中的点 * O(log(n)^d + k) 时间,其中 k 是矩形中的点数。
这对我来说表明它不应用分数级联。
提炼的问题
因此,要回答上述问题,我只需要知道是否有任何具有分数级联的二维范围树的库具有复杂的范围计数查询,所以我不去重新发明任何轮子,或者你能帮我吗?编写/修改上述资源以执行该复杂性的查询?
如果您可以为我提供任何其他方法以任何其他方式实现二维点的范围计数查询,也不要抱怨!