Apparently my teacher believes that even if we don't have time to learn stuff (nor enough examples) we should move on, so I now need to know how to make Floyd-Warshall's and Warshall's algorithms in clisp.
As I did with prolog, my problem is to generate the adjacency matrix from the graph, i开发者_如何学Gon this case it would be a list of lists, e.g.:
((A B) (A C) (A D) (B C) (C D))
That should generate:
((0 1 1 1) (1 0 1 9) (1 1 0 1) (1 9 1 0))
I've got this:
(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
)
Any help is greatly appreciated.
Also, and kind of off-topic: If I could solve my own question, should I reply myself for the sake of having an answered question?
I converted the Wikipedia pseudo-code into Common Lisp with type declarations. The return type declaration is non-standard, I used SBCL. I guess this won't run but it might give you an idea how Lisp code is supposed to look like.
(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)
Note 1: If you have a 3D volume image you should have your indices like this (aref vol k j i) where k indexes z, j y and i the x-direction. That way in SBCL and presumably all other implementations the slices are consecutive in memory.
Note 2: macrolet can save quite a lot of typing. Also look at the implementation of with-arrays in this beautiful library: git://github.com/nikodemus/raylisp.git/objects/box.lisp
精彩评论