8

假设我有100万个任意形状的,任意取向的N维椭球随机散布在N维空间中。给定一组椭球体,我想“快速”确定第一组椭球体相交的所有椭球体的集合。快速椭球面相交算法

这需要一个算法。它是什么?什么是“O”复杂性?

+1

为什么?没有这个原因,这种味道“为我做作业”。 – spender 2011-06-10 00:07:11

+0

我们是否允许假设您的椭球存储在某种类似树的数据结构中,例如四叉树的N维等价物?如果不是,那么这几乎是一个* O(MN)*问题,其中* M *是该子集的大小,并且* N *是该集合的大小。 – 2011-06-10 00:09:44

+1

@spender - 优秀!这意味着答案很容易得出。原因是因为我想要使用球体族来限制任意概率分布。确定哪一个球体重叠将允许我在解决广义可能性问题时进行第一次切割。 - 不,这不是一个家庭作业问题。 – JnBrymn 2011-06-10 01:13:26

回答

6

如果您允许使用N维数据,则“O”复杂度会受到维度的诅咒的影响。 (有关更多信息,请参阅this wikipedia article)。我建议借用物理模拟并将此问题划分为“宽广阶段”和“窄阶段”:

  • 宽广阶段保守地发现潜在重叠椭圆对的极小组集合。
  • 窄阶段将可能重叠的椭圆对集合修剪为实际重叠的那些对。

窄阶段是测试任意椭圆之间相交的直接计算几何问题。对于广义阶段,您将希望使用空间结构,如空间散列,空间树(R树,Kd树,X树,UB树等)或给定的特定结构您正在加载的数据的一些特殊属性(如不平衡的树或散列)。

当前流行的方法是Kd树。有许多文档和Kd-tree的已编码版本可以很容易配置,所以我建议你看一下在线。 (Google是你的朋友)使用大多数树结构的好处是,如果设置你正在寻找十字路口是相对紧凑的,你可以只搜索一次树并找到交叉点,而不必执行多次树遍历。这将有助于缓存(来自主内存或磁盘)访问模式。相同的算法可以处理不同的元素查询。但是,您可能会从紧凑查询集属性中获益良多。

Kd-tree不会解决所有椭球的问题 - 例如,如果您有一个尺寸为N的椭球体,其主轴从(0,0,0,0,...)到( 1,1,1,1 ...),但是具有小的或无关紧要的次轴(并且此后不太相交)将仍然需要是在所有N维​​中覆盖[0,1]的节点。如果你的椭球落在[0,1]^n中,那么每个椭球将测试与上述不方便的椭球的相交。然而,使用真实世界的数据(甚至大多数都是合成的,除非你真的努力使Kd树变慢),Kd树方法应该是一个胜利。

如果您期望Kd-tree成功获得千维椭球体,那么您最好用强力搜索进行搜索。 (前面提到的维度诅咒)。但是...

如果你有一个优化的实现,那么一百万个条目并不算太坏,但如果你做了很多查询(百万),它将会是慢(大约10秒或更差)。但是,我已经看到一些令人惊叹的数字来自优化矢量化代码。 (甚至使用这种策略发布了一些产品。)有了正确的缓存一致性,暴力破解最多只需要几毫秒。这意味着C/C++中的ASM或向量内在函数 - 不确定您正在使用哪种语言。

对于大多数数据,O复杂性(不考虑维度的诅咒)应该是关于摊销O(m log n)用于查询(一旦构建树),其中m是查询集合中的省略号,n是数据集中的省略号。建立数据本身不应该比O(n log n)差。将exp(d)中的所有内容相乘,其中d是维度 - 这就是它与这类事情一致的方式。

+0

迷人!谢谢你的反馈。所以我的外带信息是,如果我可以对椭圆体的最大尺寸做一些假设,那么我可以使用Kd树快速地将空间剔除到一个更容易处理蛮力计算几何问题的尺寸。 – JnBrymn 2011-08-04 01:54:31

+0

基本上是的。如果你真的需要,因为空间的限制,你可以从磁盘上做到这一点,因为树的遍历比蛮力的带宽更少。但是,一个经过优化的强力解决方案(如果归因于我不知道的要求)仍然可以工作。实际上,我已经发布了在每帧几毫秒内暴力类似类似问题的游戏,但这是一个非常仔细的优化。 – Kaganar 2011-08-04 03:59:33

+0

如果您不想使用预先推出的Kd-Tree实现,而是宁愿使用自己的结构,如果椭圆体的大小相当一致,则空间哈希结构实现起来会更容易,并且可以拥有一些更好的性能取决于数据本身。 Kd树通常对数据更不可知,但有更复杂的操作会减慢它们的速度。两者都对维度高度敏感。 – Kaganar 2011-08-04 04:02:43