【问题标题】:Query points in circle areas圆形区域内的查询点
【发布时间】:2018-11-14 21:22:12
【问题描述】:

这里有图说明问题:

图中有一些特征点显示为蓝色十字。我知道所有功能的坐标(x,y)。现在我想查询圆形区域(绿色圆圈)内有哪些特征。在实践中,大约有 500 个特征和 300 个查询(300 个不同的圆、不同的中心和半径)。我知道圆的参数(位置,半径)。有没有什么好的算法可以完成这项任务?

目前我有两个想法。

  1. 最愚蠢的一个,只是遍历每个功能中的所有功能 询问。这比较慢。
  2. 一个粗略的想法。将整个图片分成一些子图片。根据子图将特征放入树状结构中,如果特征在同一个子图中,则放入同一个叶子。在每个查询中,找出圆圈覆盖的子图片,并检查这些子图片中的所有特征。

有没有人有更好的想法?

【问题讨论】:

  • 通常的算法驱动方法是使用度量树,如k-d trees,通常允许类似query_ball_point。然后,这会导致构建所有点的树,然后为每个中心/半径调用此函数。但是您的数据集有点小,很难说它是否会更快。实施良好的蛮力搜索也可能很快。
  • @sascha 的方法很好,但如果您还没有相应的库,可能需要做一些工作。一个相当简单、相当快速的解决方案是通过它们的 x 坐标对十字架进行排序(如果数据集“又高又瘦”,则选择 y)。然后对于以 (x, y) 为中心的半径为 r 的圆,您可以对叉形数组进行二分搜索以找到 x-r,然后向右移动,检查每个叉形,直到找到 x+r。 (圆圈中的每个十字都必须在这个 x 范围内。)
  • @j_random_hacker 这是一个非常好的主意。易于实施并且可能足够快。我想做个测试。

标签: algorithm


【解决方案1】:

最常见的方法是将点放入 K-D 树或类似的:https://en.wikipedia.org/wiki/K-d_tree

要查找圆内的点,您会按照与中心的距离递增的顺序获取点列表,并在距离超过圆半径时停止。

要按距离增加的顺序获取点列表,您可以使用可以同时保存点和树的内部节点的优先级队列,这样您就可以按距离顺序删除它们。

对于点(叶子),距离就是点到中心点的距离。对于内部节点,距离是从中心点到可能在该节点中的任何点的最小距离。

要搜索,只需将树的根放入优先级队列,然后重复:

  1. 移除优先队列的头部;
  2. 如果队列的头部是一个点,那么它就是树中尚未返回的最近点。你知道这一点,因为如果任何内部节点可能有更近的点,那么它会首先从优先级队列中返回;
  3. 如果队列头是内部节点,则将其子节点放回队列中

这将按照与中心点的距离递增的顺序生成树中的所有点。

【讨论】:

  • 感谢您的精彩回答。这个想法看起来很酷。我唯一担心的是我的小数据集的处理时间。因为建树可能需要很多时间。我将使用蛮力搜索方法测试这种方法。
  • @Bigplume:如果您有重复的距离查找,kd 树非常好。如果你只做一次,那么创建树是不值得的。由于您有 300 个查询(并且可能会增长),因此是否创建 kd 树将非常依赖于 CPU。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-26
  • 2010-10-31
  • 1970-01-01
  • 1970-01-01
  • 2018-10-30
相关资源
最近更新 更多