Algorithm 在大型集合中寻找相距最远球体的有效算法

Algorithm 在大型集合中寻找相距最远球体的有效算法,algorithm,collections,geometry,comparison,Algorithm,Collections,Geometry,Comparison,我收集了10000-100000个球体,我需要找到相距最远的球体 一种简单的方法是简单地将所有球体相互比较并存储最大距离,但这感觉像是算法的真正资源消耗 球体的存储方式如下: Sphere (float x, float y, float z, float radius); 方法Sphere::distanceTo(Sphere&s)返回球体的两个中心点之间的距离 例如: Sphere *spheres; float biggestDistance; for (int i = 0; i &l

我收集了10000-100000个球体,我需要找到相距最远的球体

一种简单的方法是简单地将所有球体相互比较并存储最大距离,但这感觉像是算法的真正资源消耗

球体的存储方式如下:

Sphere (float x, float y, float z, float radius);
方法Sphere::distanceTo(Sphere&s)返回球体的两个中心点之间的距离

例如:

Sphere *spheres;
float biggestDistance;

for (int i = 0; i < nOfSpheres; i++) {
    for (int j = 0; j < nOfSpheres; j++) {
        if (spheres[i].distanceTo(spheres[j]) > biggestDistance) {
            biggestDistance = spheres[i].distanceTo(spheres[j]) > biggestDistance;
        }
    }
}
Sphere*球体;
浮动最大距离;
对于(int i=0;ibiggestDistance){
biggestDistance=球体[i].distanceTo(球体[j])>biggestDistance;
}
}
}
我要寻找的是一种算法,它以某种方式以更智能的方式循环所有可能的组合(如果有的话)


项目是用C++编写的(必须是),所以任何只在C/C++中使用的解决方案都不那么感兴趣。

< P>你能把这些球存储在A中吗?如果这是可以接受的,那么您可以从查找包含相距最远球体的树节点开始。然后你可以继续沿着树往下走,直到到达各个球体。

你的问题看起来可以用图表解决。由于从球体A到球体B的距离与从球体B到球体A的距离相同,因此可以尽量减少必须进行的比较次数

我想你现在看到的是一个。您可以建立一个,然后遍历它以找到最长的距离

您可以使用的另一种方法仍然会给您一个O(n^2),但是您可以最小化必须进行的比较的数量。您可以将计算结果存储到哈希表中,其中键是边的名称(因此AB将保留从a到B的长度)。在执行距离计算之前,请检查哈希表中是否存在AB或BA

编辑


使用邻接列表法(基本上是a),你会得到O(b^d)或最坏情况下的O(| E |+| V |)复杂性。

保罗让我的大脑思考,你可以通过改变来优化一点

for (int j=0; j < nOfSpheres; j++) 
那是一大堆数学题。你可以通过查看

((x2 - x1)^2 + (y2 - y1)^2 + (z2 - z1)^2 > maxdist^2

移除sqrt直到结束。

一组
S
点中任意两点之间的最大距离称为。求一组点的直径是计算几何中一个众所周知的问题。一般来说,这里有两个步骤:

  • 找到由每个球体的中心组成的三维凸包——例如,使用CGAL中的实现

  • 查找外壳上相距最远的点。(船体内部的两点不能是直径的一部分,否则它们将位于船体上,这是一个矛盾。)

  • 使用quickhull,您可以在O(n log n)的平均运行时间和O(n2)的最坏运行时间中执行第一步。(实际上,quickhull的性能明显优于所有其他已知算法。)如果可以保证球体排序的某些属性,则可以保证更好的最坏情况界限,但这是另一个主题


    第二步可以用Ω(h logh)表示,其中
    h
    是船体上的点数。在最坏的情况下,
    h=n
    (每个点都在船体上),但如果有数千个随机球体,这是不太可能的。通常,
    h
    将比
    n
    小得多。这里的

    只是为了澄清一下,你想要的是比O(n^2)(不好)更好的东西。嗯……距离()服从三角形不等式吗?distanceTo()是中心到中心还是表面到表面?球体在向量空间中有坐标吗?它是在欧几里德空间中,还是在度量曲线周围有黑洞?不管怎么说,你从哪里得到这些球体的?在eBay上可以出售的球体内部有什么有趣的东西吗?因为你似乎有很多这样的球体?@Craig如果它们是在实线上,那么排序将是n log(n),而查找最小和最大坐标则只有O(n)。假设半径或曲面不是问题BFS搜索提供了O(b^d)复杂度或O(|E|+|V|))@Mark:是的,这是家庭作业。你怎么猜到的?(除了CS老师收集了大量无法控制的数据之外。)@Craig:是的,我知道还有一些改进可以做——但我感觉我遗漏了一些东西=保罗:哈哈,我认为球体的内部充满了空洞。如果你想买一些,我相信我们可以安排一些事情不,这仍然是O(n^2),但它将支票的数量减少了一半(我也即将发布)。是的,我知道。sqrt是昂贵的。我想知道,如果在dim N>1的某个空间中有坐标,使用主分量是否会有所帮助。你不需要检查maxdist^2,因为平方距离已经存储在maxdist中了。真的,我不知道BFS是一个如此低效的算法。我的眼睛已经睁开了。构建邻接列表所需的时间与暴力解决方案所需的时间一样长。我也考虑过树结构,但我还没有查看BSP树,谢谢您的回复。=)+1:在看到这篇文章后,我已经删除了我的帖子,因为这篇文章是一个超集,是一个更好的答案。我本来会更详细地描述这些步骤,但这是家庭作业。然而,CGAL提供了源代码,因此了解这一点是了解这里发生了什么的一个很好的开始。在谷歌搜索了一会儿之后,我想我也应该添加这个链接:@JohnFeminella-这个概述链接似乎已经死了。我正在处理一个类似的问题,我点击了这个链接:-(
    distance = sqrt((x2 - x1)^2 + (y2 - y1)^2 + (z2 - z1)^2)
    
    ((x2 - x1)^2 + (y2 - y1)^2 + (z2 - z1)^2 > maxdist^2