有界线集合相交的高效算法

Posted

技术标签:

【中文标题】有界线集合相交的高效算法【英文标题】:Efficient algorithm for intersection of a collection of bounded lines 【发布时间】:2017-11-18 23:33:43 【问题描述】:

我有一组成对的数字,需要有效地找到包含给定值的成对集合。

给定以下数字对的表示形式

public class Line

    public double Start  get; set;  //is always < end
    public double End  get; set; 

Lines 的集合可以在视觉上像下面这样布局(黑线)

垂直的红线是相交标准(只是一个简单的数字,比如 10.123)

我正在寻找一种有效的算法,该算法仅返回与红色相交的黑线,假设搜索执行的频率大于 Line 添加到集合的频率。 (显然假设集合很大)

到目前为止,我的最佳解决方案是

    在创建到两个排序列表时插入行。一个排序在Start,另一个排序在End 对起始有序列表进行二分搜索,以查找起始大于交集条件的第一行的索引。 (理论上,包括该索引和该索引之后的所有线都不相交) 对最终有序列表重复 (2) 中的类似逻辑 比较索引并选择剩余迭代次数最少的列表来解决 手动遍历所选列表的其余部分以查找交叉点

【问题讨论】:

lines.Where(l =&gt; l.Start &lt;= criteria &amp;&amp; l.End &gt;= criteria) 会不会太低效?还是我过于简单化了? 这需要点击集合中的每个项目。 根据有多少范围,将范围划分为范围桶(一个范围可以在多个范围桶中)可能会导致比二分查找更少的比较,并且可能更容易并行化跨度> 也许你想要Interval tree? @dbc Ahh Interval Tree 完美地描述了我的确切问题,谢谢。我会找到一些实现并运行一些性能测试。它肯定比我的滚动解决方案更快。作为答案发布,我会接受。 【参考方案1】:

您的Line 类代表ℝ 中的interval。您有大量这样的间隔,并且希望在比线性时间更好的时间内找到与某个点重叠的那些。

interval tree 是满足您要求的一种可能解决方案:

查询需要O(log n + m)时间,其中n是区间总数,m是与找到的查询点的重叠数。 构造需要O(n log n)。 存储需要O(n) 空间。

Codeplex 的示例实现(我尚未测试)。对于其他人,请参阅C# Interval tree class。

要与相关结构segment tree 进行比较,请参阅What are the differences between segment trees, interval trees, binary indexed trees and range trees?。

【讨论】:

【参考方案2】:

这可能应该通过两个并行搜索器来完成,但是... 由于您已经管理了两个列表,请尝试以下操作:

搜索第一个 .Start 值 > ValuePoint。 (超出此索引的所有值显然无效)

int idx_start = Lines.FindIndex(x => x.Start > ValuePoint);

按 [.End] 的值对列表进行排序 鉴于您的列表已经排序,此排序永远不会是 O(n) 操作, 应该平均到O((i) log (i)),其中i = Index 是找到的第一个值。 当然,i 可能是= n

EndComparer ecomp = new EndComparer();
Lines.Sort(0, idx_start, eComp);

EndComparer:

public class EndComparer : IComparer<Lines>

    public int Compare(Lines lineX, Lines lineY)
    
        return lineX.End.CompareTo(lineY.End);
    

然后找到第一个.End值>ValuePoint

int idx_end = Lines.FindIndex(0, idx_start, x => x.End > ValuePoint);

if (idx_end > -1)

    //All values in the range [idx_end; idx_start] are valid
    //If idx_end = 0 then all pre-selected values are valid [0; idx_start]
 else 
    //All value in the range are non valid

【讨论】:

以上是关于有界线集合相交的高效算法的主要内容,如果未能解决你的问题,请参考以下文章

高效的 Minkowski 和计算

怎么高效学习数据结构和算法?

水塘抽样算法

插入排序算法,就这么简单

Elasticsearch调优篇 02 - 高效求交算法大比拼

高效学习排序算法