2016-09-21 34 views
0

我試圖實現Clojure中的布娃娃物理。我的模型具有序列多維座標X和矩陣的距離約束中號,在鬆弛算法的一部分需要的。Clojure的 - 功能鬆弛算法

總的想法是,如果一個矩陣元素m_ij異於零我要修改座標X_Ix_j的方式使得它們的距離等於M_ij。假設每個x_n是一個2D/3D座標,我知道如何進行正確的計算。

現在,作爲中號每個條目會影響兩個座標我不能想辦法用mapreduce正確遍歷座標。我可能會把loop, recur這兩個調用放在一起來模仿一個命令,但我希望有一個更好的方法(尤其是因爲它導致看起來很混亂的代碼)。

你知道的迭代一個二維矩陣和修改多個向量項在此過程中的功能呢?

+0

,想到的第一件事是在對O映射f點,而不是點值,然後重新組合這些結果。 –

+0

你考慮過嗎? '([x(範圍10)y(範圍5)] ...)' – Josh

回答

0

我覺得reduce-kv抓住了這一模式的精髓得好:

(reduce-kv (fn [x' [i j] d] ;; x' — accumulator (vector of coordinates) 
          ;; [i j] — Matrix coordinates 
          ;; d — Matrix value (distance) 
      (let [[x'ᵢ x'ⱼ] (update-distance (nth x' i) 
               (nth x' j) 
               d)] 
       (assoc x' i x'ᵢ j x'ⱼ))) 
      x ;; Initial coordinates 
      M) ;; Matrix 

的幾個注意事項:

  • update-distance計算一個新的座標對從最初的對座標和距離
  • 我們使用assoc來「更新」x。所以x應該是一個矢量(任何關聯的工作,但一個載體似乎是自然的選擇。
  • 矩陣M必須滿足clojure.core.protocols/IKVReduce協議。 如果沒有,你可以提供一個實現,或者你可以只需編寫一個可生成相應鍵值對的函數,然後使用reduce就可以了。另一種方法是使用持久映射將M作爲稀疏矩陣來實現。這應該是微不足道的補充。
+0

謝謝Nathan Davis,我不知道'''reduce-kv'''。我認爲它確實是我需要的。我將結合Charles Duffy的思想只對約束進行迭代 - 它將節省大量無約束點的迭代,從O(N^2)到O(N)。出於好奇,除了實現IKVReduce協議之外,按照您的建議,還有其他什麼方式來生成鍵值?矩陣只是向量的向量,所以如果不創建我自己的類型,我只能以這種方式迭代行。 – waechtertroll

+0

'IKVReduce'用於向量。所以你可以使用嵌套的'reduce-kv'調用 - 每個矩陣維度一個。或者,您可以在每個維度的'range'範圍內使用一對嵌套'for',並生成一個元組序列[ij d]。一般來說,爲所有感興趣的矩陣座標生成一系列元組的任何方式都可以工作。讓我知道你是否想要更多細節,然後我將它添加到答案中。 –

+0

是的,嵌套'''reduce-kv'''電話來到我腦海的第一件事。我只是想知道是否有一種方法直接將生成的元組作爲關鍵參數傳遞給reducer函數。 – waechtertroll