如何解决邻接矩阵/ Floyd / Warshall以Lisp表示
|| 显然,我的老师认为,即使我们没有时间学习东西(也没有足够的例子),我们也应该继续前进,所以我现在需要知道如何使Floyd-Warshall's和Warshall's算法变得一帆风顺。 就像我在序言中所做的那样,我的问题是从图生成邻接矩阵,在这种情况下,它将是列表的列表,例如:((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
)
任何帮助是极大的赞赏。
另外,还有种题外话:如果我可以解决自己的问题,我是否应该回答自己的问题?
解决方法
我使用类型声明将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体积图像,则应该具有这样的索引
(are vol k j i),其中k索引z,j y和i在x方向。那样
在SBCL中以及大概所有其他实现中,切片在内存中是连续的。
笔记2:
宏可以节省很多输入。还可以在这个漂亮的库中查看with-arrays的实现:git://github.com/nikodemus/raylisp.git/objects/box.lisp
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。