lisp 中的邻接矩阵/Floyd/Warshall

Posted

技术标签:

【中文标题】lisp 中的邻接矩阵/Floyd/Warshall【英文标题】:adjacency matrix/Floyd/Warshall in lisp 【发布时间】:2011-09-01 06:54:12 【问题描述】:

显然我的老师认为,即使我们没有时间学习东西(也没有足够的例子),我们也应该继续前进,所以我现在需要知道如何将 Floyd-Warshall 和 Warshall 的算法用 clisp 编写。

正如我对 prolog 所做的那样,我的问题是从图中生成邻接矩阵,在这种情况下它将是一个列表列表,例如:

((A B) (A C) (A D) (B C) (C D))

应该会生成:

((0 1 1 1) (1 0 1 9) (1 1 0 1) (1 9 1 0))

我有这个:

(defun floyd(graph)
    (setf l (length graph)) 
    (setf mat (matrix l graph))
)

(defun matrix(l graph)
    (setf matrix (make-array (list l l)))
    (dotimes (i l)
        (dotimes (j l)
            (if (= i j)
                (setf (aref matrix i j) 0)
                (setf (aref matrix i j) ???)
            )
        )
    )
    matrix
)

非常感谢任何帮助。

另外,还有点题外话:如果我能解决自己的问题,我应该回答自己以得到答案吗?

【问题讨论】:

如果您以 3 分或更高的分数回答自己的问题,则有一个 Self Learner badge。我认为这是关于是否可以接受自己回复解决方案的提示。 作为更多惯用代码的开始,对于lmatmatrix,请使用let 而不是setf CLISP 是一种实现,语言称为 Common Lisp 或简称 CL。您还需要声明变量(例如使用 LET)。设置任意未定义的变量不是一个好主意。也不要在一行中使用单括号格式化代码。 作为一个热身练习,考虑编写一个返回图表节点的函数,例如(A B C D) 如果您使用pure functions 解决问题而不是依赖副作用,您的才华将会给您的老师留下深刻的印象。看看能不能去掉SETF的使用。 【参考方案1】:

我将 Wikipedia 伪代码转换为带有类型声明的 Common Lisp。 返回类型声明是非标准的,我使用了 SBCL。 我想这不会运行,但它可能会让你知道 Lisp 代码应该是什么样子。

(defparameter *n* 5)
(defparameter *path*
  (make-array (list *n* *n*)
          :element-type '(unsigned-byte 64)))


(defun floyd-warshall (path)
  (declare (type (simple-array (unsigned-byte 64) 2) path)
       (values (simple-array (unsigned-byte 64) 2) &optional))
  (destructuring-bind (y x) (array-dimensions path)
    (unless (= y x)
      (break "I expect a square matrix, not ~ax~a." x y))
    (macrolet ((p (j i)
         `(aref path ,j ,i)))
      (dotimes (k x)
    (dotimes (i x)
      (dotimes (j x)
        (setf (p j i)
          (min (p j i) (+ (p k i)
                  (p j k)))))))))
  path)

注 1: 如果你有一个 3D 体积图像,你应该有这样的索引 (aref vol k j i) 其中 k 索引 z、j y 和 i 是 x 方向。那样 在 SBCL 和可能所有其他实现中,切片在内存中是连续的。

注2: macrolet 可以节省相当多的打字。还要看看这个漂亮的库中 with-arrays 的实现:git://github.com/nikodemus/raylisp.git/objects/box.lisp

【讨论】:

以上是关于lisp 中的邻接矩阵/Floyd/Warshall的主要内容,如果未能解决你的问题,请参考以下文章

邻接矩阵中的 Dijkstra 算法

将 arma::mat 邻接矩阵转换为 C 中的 igraph 图 (Rcpp)

将邻接列表转换为 R 中的二进制矩阵

邻接矩阵无向图

图-图的表示方法

图的存储结构:邻接矩阵(邻接表)&链式前向星