【问题标题】:Finding All Intervals That Overlap a Point查找与点重叠的所有区间
【发布时间】:2015-02-20 22:39:12
【问题描述】:

考虑一大组一维的浮点区间, 例如

 [1.0, 2.5],                1.0 |---------------|2.5

 [1.5, 3.6],                      1.5|---------------------|3.6

 .....

希望找到包含给定点的所有区间。例如给定point = 1.2,算法应该返回第一个区间,如果给定point = 2.0,它应该返回上例中的前两个区间。

在我正在处理的问题中,这个操作需要在大量的时间间隔内重复大量的次数。因此,暴力搜索是不可取的,性能是一个重要因素。

在搜索之后,我发现这个问题是在计算几何的上下文中使用间隔跳过列表来解决的。我想知道是否有任何简单、高效的 C++ 实现可用。


编辑:为了更准确地了解问题,有 N 个区间,对于 M 个点,应该确定哪些区间包含每个点。 N 和 M 是大数,其中 M 大于 N。

【问题讨论】:

  • 为什么要跳过列表?跳过列表用作将键映射到值的有效数据结构;你只是有一个搜索问题。我想你想要一个interval tree
  • 我看不到这里需要跳过列表的地方。测试一个点是否在一个区间中基本上是 2 次比较,所以如果你有 N 个区间,你将需要 2N 次比较。这将是一个简单的 O(N) 算法,并且由于您的平均 PC 每秒可以进行几百万次比较,您应该会在眨眼之间得到答案。
  • kuroi:如果你有索引数据结构,它比 O(N) 更快
  • 当然可以,但是只有几千万或更多的匹配才合理,这很可能不需要。如果有很多区间,那么在实际搜索中,专门的数据结构构建成本可能不值得节省。
  • @SaniHuttunen:点数大于区间数。

标签: c++ computational-geometry intervals skip-lists


【解决方案1】:

建议使用CGAL range trees

维基百科说interval trees(一维范围树)可以“有效地找到与任何给定区间或点重叠的所有区间”。

【讨论】:

  • 构建时间以 n log(n) 为单位,因此,如果相对于要测试的点数有足够高的间隔数,这可能比蛮力更糟糕。原始问题确实没有足够精确地定义要求以选择合适的算法,恕我直言。
  • @kuroineko OP 明确表示他想要的不是蛮力搜索,而且搜索将进行多次。
  • ...在大量间隔上。正如第一条评论所说,它归结为定义哪个大比其他许多大。
  • @Jason S,正如您所提到的,区间树是我遇到的第一个选项。我在 boost 中厌倦了 interval_map 和 Continuous_interval。但它没有给我包含给定点的区间列表。然后我在 CGAL 中遇到了这个:doc.cgal.org/latest/Interval_skip_list/…。然而,我希望有一个类似于github.com/ekg/intervaltree 的简单而整洁的解决方案
  • @Jason S:按照您的建议,在区间跳过列表和区间树之间来回切换后,我发现了这个实现 (stackoverflow.com/a/21327959/1911163),它找到了包含给定点的所有浮点区间一个简短的独立代码。
【解决方案2】:

如果您的间隔分布允许,则可能值得考虑网格化方法:选择一些网格大小s 并创建一个列表数组。每个k-th 列表都会枚举与“单元格”[k.s, (k+1).s[ 重叠的区间。

然后,查询相当于查找包含查询点的单元格(O(1))并报告列表中有效包含它的所有区间(O(K))。

预处理时间和存储都是O(I.L+G),其中I 是间隔数,L 是平均间隔长度(以网格大小表示),G 是网格单元的总数。 s一定要慎重选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 2014-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多