【发布时间】:2012-02-22 05:20:18
【问题描述】:
我正在寻找一种有人可以访问的算法,该算法将计算包含一组其他边界球的最小边界球。我已经考虑了一段时间,并提出了一些初步的解决方案,但我认为这些不一定是最准确或计算成本最低(最快)的。
最初的想法
我的第一个解决方案是最简单朴素的一个,就是将球心平均得到中心点,然后计算计算出的中心到每个球心的最大距离加上它的半径,作为半径。所以伪代码如下:
function containing_sphere_1(spheres)
center = sum(spheres.center) / count(spheres)
radius = max(distance(center, spheres.center) + radius)
return Sphere(center, radius)
end
但是我觉得它在计算上并不便宜,也不是很准确,因为生成的球体可能比它需要的大得多。
第二个想法
我的第二个想法是使用迭代算法来计算最小边界球。它是通过连续测试另一个球体来计算的,如果测试的球体在边界内,则什么都不做,否则从两个可用球体计算一个新的边界球。如果新边界球体延伸到球体表面,则新边界球体的中心位于两个中心之间的向量的中间,半径是该线长度的一半(从新中心到任一球体表面)。
function containing_sphere_2(spheres)
bounds = first(spheres)
for each sphere in spheres
if bounds does not contain sphere
line = vector(bounds.center, sphere.center)
extend(line, bounds.radius)
extend(line, sphere.radius)
center = midpoint(line)
radius = length(line) / 2
bounds = Sphere(center, radius)
end
end
return bounds
end
最初我认为这是要走的路,因为它是迭代的并且看起来在逻辑上相当一致,但是在阅读了一些之后,最值得注意的是 Emo Welzl 的文章“Smallest enclosure disks (balls and ellipsoids)”我不太确定。
Welzl 算法
据我了解,该算法的基础是 3 维中一组点上的最小边界球最多可以由 4 个点(位于封闭球的表面)确定。因此,该算法采用迭代方法,选择 4 个点,然后测试其他点以查看它们是否在内部,如果它们不是以新点为特征的新边界球体。
现在算法严格处理点,但我认为它可以应用于处理球体,主要的复杂性是在构造封闭球体时考虑半径。
回到问题
那么,为一组给定球体创建最小边界球体的“最佳”算法是什么?
我在这里描述的其中之一是答案吗?一些伪代码或算法会很棒。
【问题讨论】:
-
如果您使用加权质心(按半径)而不是纯质心,似乎可以使您的幼稚方法起作用。也就是说,边界球的中心应该比小球的中心更靠近大球的中心。
-
不幸的是,我认为这种天真的方法行不通,hacksoflife.blogspot.com/2009/01/… 似乎表明有很多反例它会崩溃。它将创建一个封闭的球体,但不一定是最小的。
-
This 2008 paper by Thomas Larsson 有一个有用的边界球算法参考书目(用于点的集合,而不是球的集合)。
-
我不是数学家(可能应该感兴趣地关注这个),但是......是否值得在球体周围画一个边界 box 然后画一个边界围绕那个?我想它仍然需要大量计算来确定盒子的大小,但它不会简化计算每次迭代的原点移动吗?此外,它仍然不一定是最小的,但会比具有固定来源的选项 1 更小。只是一个想法......
-
事实证明 Welzl 的算法不适用于球体,请参阅我在 inf.ethz.ch/personal/emo/DoctThesisFiles/fischer05.pdf 的论文,p。 93 为反例。但是,正如@hardmath 的回答中所述,CGAL 中提供了一个非常快速的 C++ 实现。