是否可以有效地计数与数字线上的单个点P重叠的线段的数量
Is it possible to efficiently count the number of line segments that overlap a single point P on a number line?
是否可以有效地计算与数字线上的单个点P
重叠的线段数量?
所有线段都位于一条数字线上(这是一个1-D
世界,而不是3-D
世界)。
每个线段具有起始坐标X1
和结束坐标X2
。
示例:
Line segment A spans from X1==1 to X2==3
Line segment B spans from X1==2 to X2==4
Line segment C spans from X1==3 to X2==5
Line segment D spans from X1==1 to X2==4
----------------------------------------
Ex1: Line segments that overlap point P==2: A,B and D >>> overlap count==3.
Ex2: Line segments that overlap point P==7: None >>> overlap count==0.
Ex3: Line segments that overlap point P==3: A,B,C and D >>> overlap count==4.
当然,如果只有4个线段,那么代码很简单。然而,如果有一个由4亿条线段组成的巨大空间数据库,那么搜索速度非常慢。
是否有任何算法可以有效地搜索线段列表中的重叠总数?
到目前为止我正在查看的内容
- 关于空间索引搜索算法的文章
- 间隔树(看起来很有前途)
- 分段树(看起来很有前景)
- R树
如果按起始值对列表进行排序,然后再按长度(对于相同的起始值)进行排序,则最终得到高效算法的根。
sort the list by starting value
for the same starting value, sort by length (longest first)
然后,当你需要与给定点p重叠的线段数量时:
for a given value p
find the points in the list with starting value <= p (binary search - fast)
for each starting value, start with the longest length
if it spans the point of interest, increment counter
if not, go to the next smaller start value
keep going until you have reached the smallest starting value
它并不完美,但比搜索10M个点要好得多(尽管最初的排序显然需要一些时间。但你只需要做一次)。
在单个数组中对查询点和区间端点进行越来越多的排序;对于每个点,保留一个标志,告诉它是间隔开始、间隔结束还是查询。
将计数器初始化为零并扫描列表。启动会增加计数器;末端使其减小;查询通过读取计数器来知道重叠间隔的数量。
时间(N+M)。如果可以使用特殊排序,则为对数(N+M。
如果不允许对查询点进行排序,只需对间隔端点进行排序。在单个线性扫描中,可以计算每个端点之后的重叠数量。
对于给定的查询点,您可以通过二分搜索找到相关的端点,从而获得重叠计数。
M个区间和N个查询点的M.Log(M)+N.Log(M)。
如果不允许对间隔进行排序,只需对查询点进行排序即可。
依次处理每个区间,通过二分搜索找到它重叠的第一个查询点,并增加它重叠的所有查询点的计数器。
N.Log(N)+M.Log(N)+O,其中O是间隔/查询重叠的总数。
如果根本不允许排序,请针对每个间隔对每个查询进行详尽的测试,N.M.
看看区间树或分段树可以帮助解决这类问题。这个答案有一些很好的例子来说明这些技术是如何帮助你的。
首先要意识到,你不能比O(N)做得更好,因为你需要至少看一次每个线段。(其中N=线段数量)
让我们有一个数组Line_segments_at,它存储通过每个点的线段数。
首先,我们需要将此数组初始化为0。然后,当我们看第i个线段时,我们需要做:
for(int j=x1[i];j<=x2[i];j++)
Line_segments_at[j]++;
对于每个查询点k,我们可以简单地将结果返回为Line_segments_at[k]。
- Ardunio UNO解决了多个重叠的定时器循环
- 试试完美的正方形,你能给点小费吗
- 无法将结构注册为增强几何体3D点
- C++将浮点指针值舍入为小数位数
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 为什么在浮点中从大到小会引入更多的误差
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- 如何对点云数据进行排序
- USB-HID 读/写(重叠)等待单个对象不返回C++
- 具有单个函数的两个点的距离和坡度
- 点云库 - 如何将单个 RGB 值分配给整个点云
- 查找与点重叠的所有间隔
- 许多函数的单个DLL入口点
- 质量控制 与图形上的单个点进行交互
- 是否可以有效地计数与数字线上的单个点P重叠的线段的数量
- c++:抗锯齿点重叠(alpha混合)
- 在小于0 (N)的时间内找出点是否在N个(可能重叠)矩形中的一个内
- 如何在opencv中撤消单个点的透视变换
- 数组和单个数据点使用指针之间的区别