Clojure - 功能松弛算法

时间:2016-09-21 14:59:40

标签: algorithm clojure functional-programming

我正在尝试在Clojure中实现布娃娃物理。我的模型有一个多维坐标的 x 序列和一个距离约束的矩阵 M ,在松弛算法的一部分中需要。

一般的想法是,如果矩阵条目 m_ij 与零不同,我必须以这样的方式修改坐标 x_i x_j 他们的距离等于 M_ij 。假设每个 x_n 是一个2D / 3D坐标,我知道如何正确计算。

现在,由于 M 的每个条目都会影响两个坐标,我无法想到使用mapreduce来正确迭代坐标的方法。我可以把两个loop, recur的调用放在一起来模仿命令,但我希望有更好的方法(特别是因为它导致代码看起来真的很混乱)。

您是否了解迭代二维矩阵并修改过程中多个向量条目的功能方法?

1 个答案:

答案 0 :(得分: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值距离,但这应该是无关紧要的。