使用LISP查找有向无环图(DAG)中单个节点的所有路径

时间:2014-03-11 00:21:37

标签: search lisp directed-acyclic-graphs

我遇到了一些问题,使用lisp来解决下面详述的问题。

这是我的人工智能的家庭作业问题之一,涉及将无方向图转换为有向无环图,然后对其进行搜索以获取给定节点的所有路径。

问题机构如下:

  

问题1:考虑类中使用的示例图   说明不同的搜索算法。我们的原始图表   没有引导。让它定向,并假设   以下表单设置节点之间的方向:

(setf
  (get 's 'successors) '(a d)
  (get 'a 'successors) '(b d)
  (get 'b 'successors) '(c e)
  (get 'c 'successors) '()
  (get 'd 'successors) '(e)
  (get 'e 'successors) '(f)
  (get 'f 'successors) '())
     

不以任何方式订购继承人。让节点进入   这个有向图表示任务,每个任务都需要一个   已知的时间量,由以下setf形式定义

(setf
  (get 's 'time-consumed) 3
  (get 'a 'time-consumed) 2
  (get 'b 'time-consumed) 4
  (get 'c 'time-consumed) 3
  (get 'd 'time-consumed) 3
  (get 'e 'time-consumed) 2
  (get 'f 'time-consumed) 1)
     

此外,让有向边代表优先关系   节点之间,如果有任务A到边缘   任务B,然后必须完成任务A才能开始工作   任务B(这是你的拓扑排序问题   熟悉CS 253 / CS 501)

     

编写一个返回所有列表的过程ALL-PATHS   从给定节点开始的非圆形路径。例如,

(all-path 's)

((S A D E F)
 (S A B E F)
 (S A B C)
 (S D E F))
     

提示:必须更改EXTEND功能才能使用SUCCESSOR   财产(而不是NEIGHBORS财产)。为了得到所有   队列前面的路径不完整,一起使用SORT   使用FIRST-PATH-INCOMPLETE-P,一个返回T if的谓词   它的两个论点中的第一个是不完整的路径,即

`(defun first-path-incomplete-p (p1 p2)
   (not (endp (extend p1))))`                            

到目前为止我有这个:

(setf
  (get 's 'successors) '(a d)
  (get 'a 'successors) '(b d)
  (get 'b 'successors) '(c e)
  (get 'c 'successors) '()
  (get 'd 'successors) '(e)
  (get 'e 'successors) '(f)
  (get 'f 'successors) '())

(setf
  (get 's 'time-consumed) 3
  (get 'a 'time-consumed) 2
  (get 'b 'time-consumed) 4
  (get 'c 'time-consumed) 3
  (get 'd 'time-consumed) 3
  (get 'e 'time-consumed) 2
  (get 'f 'time-consumed) 1)

(defun all-paths (start)
  )

(defun extend (path)
  (print (reverse path))
  (mapcar #'(lambda (new-node) (cons new-node path))
    (remove-if #'(lambda (successor) (member successor path))
      (get (first path) 'successors))))

(defun first-path-incomplete-p (p1 p2)
  (not (endp (extend p1))))

此外,我修改了她从课堂引用的图表以反映新的关系:

DAG

我的问题是如何使用lisp来解决这个问题,以及如何使用她想要的程序,例如extendfirst-path-incomplete-p。我在网上找到的例子涉及源和目的地,而我试图从单个节点找到所有路径。

另外使用源和目的地我知道最好的第一次搜索甚至深度优先可能对这个问题有益,但是当我们只用一个起点来应用它们时我会感到困惑。

感谢任何帮助,建议或评论!

由于


更新

经过一些细微的修改,我取得了巨大的成功。不知道为什么,但它只是为我点击。我最后修改了我在之前的作业中做过的最佳优先搜索实现,现在从单个节点生成所有路径。不确定cond语句的必要性,但相关更改发生在此处:

(defun closerp (path-1 path-2)
  (< (get (first path-1) 'time-consumed)
     (get (first path-2) 'time-consumed)))

(defun all-paths (start &optional (queue (list (list start))))
  (cond ((endp queue) nil)
    ;((equal start (first (first queue)))
    ;(reverse (first queue)))
  (t (all-paths start
    (sort (append (extend (first queue))
      (rest queue))
        #'(lambda (p1 p2)
          (closerp p1 p2)))))))

唯一剩下的就是实施first-path-incomplete-p,我认为这会使我的结果变得有点紧张,因为我的(all-paths 's)

示例的路径比预期更多

例如,当我执行相同的查询时,我得到了这个:

Break 1 [2]> (all-paths 's)

(S) 
(S A) 
(S A D) 
(S A D E) 
(S A D E F) 
(S D) 
(S D E) 
(S D E F) 
(S A B) 
(S A B E) 
(S A B E F) 
(S A B C) 
NIL

这些都是有效的路径,但它没有选择与她的示例相同的路径,这对我来说就像是最佳路径。

0 个答案:

没有答案