【问题标题】:Data structure to pre-process given set of N points and given a query parallel strip output all points lie within the strip预处理给定的 N 个点集并给定查询并行条输出的数据结构,所有点都位于条内
【发布时间】:2014-11-26 06:27:14
【问题描述】:

我被要求设计一种算法来预处理给定的一组 N 个点,例如给定一个查询并行条,输出所有点都位于条带内。

我尝试设计算法,但我只能单独解决查询。

我不知道使用哪种数据结构并对给定的 N 个点进行预处理,以便我可以轻松回答查询。

我只需要知道如何去做,以及它会有什么复杂性。

【问题讨论】:

  • 已知条带平行于 x 轴或 y 轴吗?
  • “条”是二维的吗? (也就是说,你所有的点都是二维的吗?)
  • 当然是二维的,否则就太容易了。条带不平行于轴,它们彼此平行。
  • 条带方向固定吗?

标签: algorithm data-structures computational-geometry lines points


【解决方案1】:

解决此类问题的常用方法是使用bounding volume hierarchy

考虑将点装在盒子里,那些盒子装在更大的盒子里,等等......如果你的一个大盒子完全在条带之外,那么你不需要检查它。但是,如果它在条带内,那么您将不得不看看里面有什么。如果里面有一个不在条带中的盒子,你也不必检查那个盒子的内容。当然,关键是包装这些框,这样您通常可以跳过检查很多子框和点。

(请注意,并非所有 BVH 都使用盒子——有些使用球体,有些使用 simplices,有些使用有点奇怪的分区,但大多数使用盒子。)

R-trees 在大型数据库中的二维应用程序中很受欢迎。您还可以使用 space partitioning 结构(或多或少只是 BVH 的一种特殊化),您可能会这样做,因为已经有很多用于 K-d 树(一种空间分区)的库。

无论你最终采用何种结构,顶层算法都将保持不变:

# This algorithm could be implemented with a stack or recursively
# instead of maintaining a potentially very long list of nodes.
nodes = { top_level_node }
loop while there are nodes left to process
    set node = first element of nodes
    remove node from nodes
    if node does not intersect strip continue loop
    if node directly contains points that are within the strip add them to the output
    if node directly contains subnodes that intersect the strip add them to nodes
end loop

根据您使用的结构,对于固定数量的维度,您可以预期一般行为为O(o log n),其中n 是总点数,o 是条带内的点数。请注意,这个有点幼稚的算法使用O(o) 内存,但如果使用堆栈或递归,它可以使用O(log n)

Box2D 物理引擎有一个不错的 2D BVH 实现,非常容易使用。 (许可证看起来非常宽松。)Box2D 的 BVH 曾一度基于 Bullet 的(并且可能仍然如此)。 Bullet 物理引擎有一个 3D BVH 实现,我之前已经转换为 2D,它有一个 zlib(非常宽松)许可证。实时物理引擎的问题在于,他们通常对获得最优树不感兴趣——他们感兴趣的是在几毫秒内“尽可能好”,因为他们没有时间进行优化。但是,它们可能足以满足您的目的。

Rosettacode 甚至有一个K-d tree entry——但你的里程可能会有所不同,因为我希望这些条目比一个使用良好的库(例如 FLANN,我相信它包含一个 K-d 树。) /p>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-14
    • 2014-06-02
    • 1970-01-01
    • 2015-03-05
    • 1970-01-01
    • 1970-01-01
    • 2021-10-16
    相关资源
    最近更新 更多