我有一个Cuboids列表,由它们的左下角和右上角的坐标定义,边缘平行于轴。坐标是双值。这些长方体密集,与一个或多个其他重叠,甚至完全包含其他。
我需要计算所有给定长方体所包含的总体积。重叠(甚至多次)的区域应该只计算一次。
例如,卷:
总音量为27 + 1 + 2 + 8 = 38。 有没有一种简单的方法(在O(n ^ 3)时间或更好?)?
答案 0 :(得分:2)
这可以使用平面扫描算法有效地解决,这是线扫描算法的直接扩展,建议here用于查找重叠矩形的总面积。
对于每个长方体,在事件队列中添加左右x坐标并对队列进行排序。现在通过长方体扫描yz平面(具有常数x值)并记录事件队列中任意两个连续事件之间的音量。我们通过在任何阶段维护与平面相交的矩形列表来做到这一点
当我们扫过飞机时,我们遇到两种类型的事件:
(1)我们看到新的长方体开始与扫掠平面相交。在这种情况下,一个新的矩形与平面相交,我们更新与扫掠平面相交的矩形区域。
(2)与飞机相交的现有长方体的末端。在这种情况下,我们必须从当前与平面相交的矩形列表中删除相应的矩形,并更新生成的矩形的新区域。
任何两个连续事件q i 和q i + 1 之间的长方体的体积等于两个事件之间的水平距离次在q i 处与扫描线相交的矩形区域。
通过使用O(nlogn)algorithm计算矩形区域作为子程序,我们可以获得一个O(n 2 logn)算法来计算总体积。长方体。但是可能有更好的方法来维护矩形(因为我们只在任何阶段添加或删除一个矩形),效率更高。
答案 1 :(得分:2)
在处理每个长方体时,如何保持一组非相交的长方体?
此系列将开始为空。
第一个长方体将被添加到集合中 - 它将是唯一的元素,因此保证不会与其他任何元素相交。
将根据集合中的元素检查第二个和后续的长方体。对于每个新的长方体 N ,对于集合中已有的每个元素 E :
如果我们使用从 N 生成的一个或多个长方体对非交叉元素进行测试结束(表示由 N 贡献的体积,那是' t在任何先前的长方体中)然后将它们全部添加到集合中并处理下一个长方体。
一旦处理了所有长方体,总体积将是已建立的非相交长方体集合中体积的总和。
答案 2 :(得分:0)
我最近遇到了同样的问题,发现以下方法易于实现并适用于 n 个维度。
首先构建一个网格,然后检查网格中的每个单元格是否与长方体重叠。长方体重叠的体积是一个或多个长方体中包含的那些单元的体积之和。
您可以使用Cartesian Product获取所有网格单元。
答案 3 :(得分:0)
我尝试了@ccssmnn建议的蜂窝方法;它有效,但是速度太慢。问题在于用于“对于每个维度,存储数组中每个长方体的最小/最大值”的数组大小。是O(n)
,因此像元数(因此,执行时间)是n^d
,例如,三个维度的单元格数是n^3
。
接下来,我尝试了@krjampani建议的嵌套扫掠线算法;快得多,但仍然太慢。我认为复杂度为n^2*log^3(n)
。
所以现在,我想知道是否有任何追索权。我读过几篇有关使用interval trees
或augmented interval trees
的帖子。这种方法是否可能具有更好的复杂性,例如n*log^3(n)
?
此外,在这种情况下,我想尽一切办法增加价值?对于点或范围查询,我可以看到按它们的(xlo,ylo,zlo)
对长方体进行排序,并为每个子树使用max(xhi,yhi,zhi)
作为增值,但无法弄清楚如何对其进行扩展以保持跟踪长方体的结合及其体积。