在方案中查找图中2个节点之间的路径

时间:2013-12-04 07:36:50

标签: scheme depth-first-search

有人可以解释为什么我有错误:

 map: contract violation
  expected: list?
  given: 'e3
  argument position: 2nd
  other arguments...:
   #<procedure>

在下面的代码中

我的预期输出是:'(e4 e5 e0)

我正在尝试使用深度优先搜索算法来查找2个节点之间的路径,代码是:

#lang racket


(define successors    ; finding successor of a node in graph
  (lambda (node graph)
    (let ((val (assq node graph)))
      (if val
          (cdr val)
          '()))))

(define make-task cons)
(define task-node car)
(define task-path cdr)
(define same-node? eq?)

(define linked    ; function to find the path between 2 nodes in a graph

    (lambda (start end graph)   ; begin, end: nodes    graph: a graph                         

      (define handle-node                                
        (lambda (node path todo seen)
          (if (same-node? node end)
              (reverse (cons node path))
              (if (assq node path)
                  (process-todo todo seen)
                  (process-todo (append (map (lambda (successor)
                                                  (make-task successor
                                                             (cons node
                                                                   path)))
                                                (successors node
                                                            graph))
                                           todo)
                                (cons node seen))))))

      (define process-todo
        (lambda (todo seen)
          (if (null? todo)
              #f
              (let ((task (car todo)))
                (handle-node (task-node task)   ;;; node
                             (task-path task)   ;;; path
                             ((lambda (x y) (cdr y)) task todo) ;;; rest to do
                             seen)))))

      (handle-node  start '() '() '())))

(linked 'e4 'e0 '((e1 . e0) (e2 . e1) (e3 . e2) (e4 . e3) (e4 . e5) (e5 . e0)))

非常感谢!!

1 个答案:

答案 0 :(得分:0)

您的successor函数出现“类型”错误。 if的替代返回一个列表(实际为'()),而if的结果返回(cdr val),而不是列表(基于您的输入数据)。这是从错误消息中确认的 - 预计会list?,但会提供symbol?

看起来您的图表表示是节点名称与连接节点名称列表之间的关联。但是您的输入数据不是那种形式!尝试:

'((e1 e0) (e2 e1) ...)

顺便说一句,successor被惯用地写为:

(define (successor node graph)
  (cond ((assq node graph) => cdr)
        (else '())))