假設我有100萬個任意形狀的,任意取向的N維橢球隨機散佈在N維空間中。給定一組橢球體,我想「快速」確定第一組橢球體相交的所有橢球體的集合。快速橢球面相交算法
這需要一個算法。它是什麼?什麼是「O」複雜性?
假設我有100萬個任意形狀的,任意取向的N維橢球隨機散佈在N維空間中。給定一組橢球體,我想「快速」確定第一組橢球體相交的所有橢球體的集合。快速橢球面相交算法
這需要一個算法。它是什麼?什麼是「O」複雜性?
如果您允許使用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是維度 - 這就是它與這類事情一致的方式。
迷人!謝謝你的反饋。所以我的外帶信息是,如果我可以對橢圓體的最大尺寸做一些假設,那麼我可以使用Kd樹快速地將空間剔除到一個更容易處理蠻力計算幾何問題的尺寸。 – JnBrymn 2011-08-04 01:54:31
基本上是的。如果你真的需要,因爲空間的限制,你可以從磁盤上做到這一點,因爲樹的遍歷比蠻力的帶寬更少。但是,一個經過優化的強力解決方案(如果歸因於我不知道的要求)仍然可以工作。實際上,我已經發布了在每幀幾毫秒內暴力類似類似問題的遊戲,但這是一個非常仔細的優化。 – Kaganar 2011-08-04 03:59:33
如果您不想使用預先推出的Kd-Tree實現,而是寧願使用自己的結構,如果橢圓體的大小相當一致,則空間哈希結構實現起來會更容易,並且可以擁有一些更好的性能取決於數據本身。 Kd樹通常對數據更不可知,但有更復雜的操作會減慢它們的速度。兩者都對維度高度敏感。 – Kaganar 2011-08-04 04:02:43
爲什麼?沒有這個原因,這種味道「爲我做作業」。 – spender 2011-06-10 00:07:11
我們是否允許假設您的橢球存儲在某種類似樹的數據結構中,例如四叉樹的N維等價物?如果不是,那麼這幾乎是一個* O(MN)*問題,其中* M *是該子集的大小,並且* N *是該集合的大小。 – 2011-06-10 00:09:44
@spender - 優秀!這意味着答案很容易得出。原因是因爲我想要使用球體族來限制任意概率分佈。確定哪一個球體重疊將允許我在解決廣義可能性問題時進行第一次切割。 - 不,這不是一個家庭作業問題。 – JnBrymn 2011-06-10 01:13:26