区域搜索中的点数

时间:2013-11-07 15:50:03

标签: c++ multithreading algorithm search

我的问题接近Nearest neighbour search,但不完全正确。

对于2D空间中给定的矩形区域(与轴对齐),我需要找到属于该区域的所有点。 我可以提前准备有关我的积分的任何数据。我对点坐标有一个限制(假设我们所有的点都在X和Y坐标中从0到1的区域内)。

查询数量(地区)>>点数。因此,我的优先事项是:

  1. QueryTime - 按地区获取积分的时间。
  2. MemorySize - 我需要的额外内存大小(用于准备)。
  3. PreparationTime - 附加数据准备时间。
  4. 哪种算法适用于此?(我会很高兴看到有关该主题的书籍或文章。)


    示例:

    我有一个点坐标数组,范围从0到1:

    {0.1224,0.2345},{0.01,0.99},{0.94,0.5}

    并获取查询以查找区域中从X到0.1的0.2到0.2以及Y的0.2到0.4的所有点。

    然后我需要找到第一点{0.1224,0.2345}。

3 个答案:

答案 0 :(得分:2)

听起来你有一些竞争条件。目前尚不清楚你是如何做到的。 通常的方法是让准备单线程,冻结结构(将它作为const传递到各处),然后所有查询都可以并行运行而不需要协调,因为结构是不可变的。

另一种方法是使用KD树或Quad树。你可能会遇到你现在看到的相同种族问题。 但是如果你想尝试一下,使用随机点,或者如果你能负担得起分裂的最佳点(但在实践中应该不重要)。 你会得到一些符合O(logNP + R)的东西,其中R是结果中的点数。

http://en.wikipedia.org/wiki/Kd_tree http://en.wikipedia.org/wiki/Quadtree

答案 1 :(得分:1)

分别根据x轴和y轴对点进行排序。

获取与相应轴中的限制匹配的x和y子集。

选择范围内元素较少的那个。对于范围内的所有元素,选择落在另一个轴范围内的元素。

准备时间nlogn。

搜索时间:最糟糕的情况是n,但实际上远不如此。

此外,您可以根据您可以拥有的内存量来搜索时间(logn)^ 2或logn。

如果您有O(n ^ 2)内存,则可以根据y值对每个x值范围内的数字进行排序。在进行搜索时,必须首先在x上找到范围,然后在与该范围对应的排序列表上进行搜索。

或者,您可以在x轴排序列表中对长度为2,4,8等的非重叠范围进行排序。当你得到一个x范围时,你必须在迷你排序范围内搜索(有最坏情况下,登录范围),这些范围一起组成范围(每次搜索最多占用登录时间)。有效搜索时间是(logn)^ 2.

答案 2 :(得分:0)

正如@Sorin建议的那样,最好使用像KD树或R树这样的几何树。在你的结构准备好之后,它保持不变,你可以从不同的线程并行查询它(当然,我认为,结构的实现方式不会在查询期间改变它的状态。)

许多图书馆提供此类数据,例如Boost.Geometry有rtree,OpenCV有KDtree,详见https://stackoverflow.com/questions/1402014/kdtree-implementation-c

对于数据准备,典型的方法是递归的,并且非常适合树构造:将数据分成两半(例如,在某些枢轴上方和下面的那些上方具有X坐标的那些),递归地为每个部分构建树,合并)。

可以将递归调用分配给单独的线程。事实上,完全符合tbb::parallel_reduce和类似的并行模式。在回答这个问题时,我找到了一些papers,它遵循这个计划。