欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Lisp--Shortest Path(bfs和dfs)

程序员文章站 2024-02-27 18:52:27
...

用Lisp实现寻找有向图中最短路径(深度优先算法和广度优先算法)

先来看一下图的存储格式:

(setf min '((a b c) (b c) (c d)))

min:
Lisp--Shortest Path(bfs和dfs)

(setf min2 '((a b c) (b c d) (c d)))

min2:
Lisp--Shortest Path(bfs和dfs)

;;;将所有node中未加入的节点加入path中
(defun new-paths (path node net)
	(mapcar #'(lambda (n)
						(cons n path));;;注意此函数会依次作用于下面的参数上(mapcar的效果)
					(cdr (assoc node net))));;;取出与node关联的所有节点
;;;bfs广度优先算法
(defun bfs (end queue net)
	(if (null queue)
		nil
		(let ((path (car queue)))
		 (let ((node (car path)))
		  (if (eql node end)
		  	(reverse path);;;方便顺序阅读
		  	(bfs end
		  		(append (cdr queue);;;注意此处的顺序
		  			(new-paths path node net));;;先将同一层次的节点都遍历
		  		net))))))
//dfs深度优先算法
(defun dfs (end queue net)
	(if (null queue)
		nil
		(let ((path (car queue)))
		 (let ((node (car path)))
		  (if (eql node end)
		  	(reverse path)
		   	 	(dfs end
		   	 		(append 
		   	 			(new-paths path node net)
		   	 			(cdr queue));;;这里的顺序是与上面bfs算法差别之一
		   	 		net))))))
//
(defun shortest-path-bfs (start end net)
	(bfs end (list (list start)) net))
//
(defun shortest-path-dfs (start end net)
	(dfs end (list (list start)) net))

以下是在lispbox-0.7中运行的结果:
Lisp--Shortest Path(bfs和dfs)
在图min中运用bfs算法时,每次调用bfs时queue的值如下:
((a))
((b a) (c a))
((c a) (c b a))
((c b a) (d c a))
((d c a) (d c b a))

在图min中运用dfs算法时,每次调用dfs时queue的值如下:
((a))
((b a) (c a))
((c b a) (c a))
((d c b a) (c a))

在图min2中运用bfs算法时,每次调用bfs时queue的值如下:
((a))
((b a) (c a))
((c a) (c b a) (d b a))
((c b a) (d b a) (d c a))
((d b a) (d c a) (d c b a))

在图min2中运用dfs算法时,每次调用dfs时queue的值如下:
((a))
((b a) (c a))
((c b a) (d b a) (c a))
((d c b a) (d b a) (c a))

也许这组测试数据更有特点:
Lisp--Shortest Path(bfs和dfs)

bfs算法在《ANSI_Common_Lisp》中已经给出,而dfs算法是我站在巨人的肩膀上的拙作(其实还是大师做了大部分工作),希望可以起到抛砖引玉的作用

参考:
《ANSI_Common_Lisp》—Paul Graham
《Introductory Combinatorics》 —Richard A. Brualdi

相关标签: 算法 lisp