Algorithm 是否有一种有效的方法来计算给定线段集之间的交点数?

Algorithm 是否有一种有效的方法来计算给定线段集之间的交点数?,algorithm,language-agnostic,geometry,computational-geometry,Algorithm,Language Agnostic,Geometry,Computational Geometry,假设在一般位置有n条线段。我如何快速计算,对于我的n段中的每一段,它与其他n-1段相交的数量 我可以在O(n2)时间内天真地做到这一点。我可以使用一个非常简单的扫描线算法(Bentley Ottmann)在O((n+k)log n)时间内找到所有交叉点,其中k是此类交叉点的数量,然后将我找到的交叉点聚合为一组计数 不过,我不需要找到十字路口;我只是想知道有多少。我不知道如何修改扫描线算法使其更快,因为它需要为每个交叉点重新排列树中的两个东西,而且我想不出任何其他技术不会遇到相同的问题 我还对如何

假设在一般位置有n条线段。我如何快速计算,对于我的n段中的每一段,它与其他n-1段相交的数量

我可以在O(n2)时间内天真地做到这一点。我可以使用一个非常简单的扫描线算法(Bentley Ottmann)在O((n+k)log n)时间内找到所有交叉点,其中k是此类交叉点的数量,然后将我找到的交叉点聚合为一组计数

不过,我不需要找到十字路口;我只是想知道有多少。我不知道如何修改扫描线算法使其更快,因为它需要为每个交叉点重新排列树中的两个东西,而且我想不出任何其他技术不会遇到相同的问题


我还对如何计算总交叉口数感兴趣。

我很难相信在一般情况下你能比宾利·奥特曼做得更好。如果不关心线段在哪里相交,可以稍微简化计算,但我不知道如何计算交叉点而不找到它们

本质上,Bentley Ottman是一种简化交叉口搜索空间的方法。还有其他方法,可能适用于线段的特定排列,但除非线段之间存在某种可预测的几何关系,否则您将无法比首先使用某种聪明的方法找到候选交点,并对每个候选交点进行单独验证


除非您的问题域有一些特定的特性,可能会提供可利用的子结构,否则我认为您最好的速度选择是采用Bentley Ottman(或类似的扫描算法)进行并行执行。(将线段裁剪成条带很简单。找出一组最佳的条带也会很有趣。)当然,这是一个实践而非学术练习;并行算法最终可能会做更多的工作;它只是利用硬件在(恒定因素)更短的时间内完成工作。

我相信扫描线方法可以被击败,这不太困难。考虑到可以计算左端点全部具有x坐标0和右端点都具有x坐标1的n个线段之间的交点数目;这正是阵列中求逆的经典问题。所以,至少在某些特殊情况下,我应该能够寻找这种子结构并以某种方式加以利用。@tmyklebu,当然,如果有一个可利用的子结构,你可以很容易地加以利用。但你必须先知道。您可以在
O(n)
中轻松地检查单位平方的情况,但是如果您没有充分的理由相信它是可能的,那么这将是愚蠢的。(类似地,对于其他特殊情况,如凸多边形集合),此类情况不是“一般情况”。B-O可以很好地处理多边形集合的情况,因为它可以通过较少的实际交点来加速。B-O可以很好地处理只有很少交点的情况。当我有一堆多边形时,我仍然能想出一些粗略的例子(画出一整堆以同一点为中心但以随机角度旋转的等边三角形)。可利用的子结构是……问题的关键。:)Chazelle的一篇论文(“报告和计算路段交叉口”)似乎使用了这种垂直分解思想,并声称我的问题有一个O(n1.695)时间算法,但它似乎依赖于一个非常不切实际的数据结构。总比没有强。对于10^6,n^2和n^1.695之间的差值约为70:1。因此,要使这样的算法实用(假设一百万条线段在正常问题域中),它必须在其内部循环中做不少于70倍的工作。据我所知,Welzl的工作是该解决方案的基础,主要成本是共轭树的构建,但可能我弄错了。查找比遍历四叉树要复杂得多,但这只是一点代数。我认为这是一个非常有趣的学术活动。玩得开心。。。。