2つのノード名(AとEなど)を取り、再帰的に使用されるオプションのパラメーター(キュー)を持つ既存のヒルクライム関数を変更しようとしています。あるパスが別のパスよりも安いかどうかを評価する関数「cheaper」を定義しようとしています。また、1つのゴールノードの代わりに、ゴールノードのリストを渡そうとしています。これらのノードの1つに到達すると、関数は評価を停止します。
問題は、入力した開始ノードと空のリストを除いて、関数が何も返さないことです。
これが私のネットワーク/グラフと関連するコストです:
(setf (get 's 'coordinates) '(0 3)
(get 'a 'coordinates) '(4 6)
(get 'b 'coordinates) '(7 6)
(get 'c 'coordinates) '(11 9)
(get 'd 'coordinates) '(2 0)
(get 'e 'coordinates) '(9 2)
(get 'f 'coordinates) '(11 3))
(setf (get 's 'cost) 0
(get 'a 'cost) 16
(get 'b 'cost) 4
(get 'c 'cost) 10
(get 'd 'cost) 5
(get 'e 'cost) 12
(get 'f 'cost) 14)
そして、これが私の修正されたヒルクライム関数です:
(defun hill-climb (start finish &optional (queue (list (list start))))
(cond ((endp queue) nil)
((member (first (first queue)) finish)
(reverse (first queue)))
(t (hill-climb start finish (append (sort (extend (first queue))
#'(lambda (p1 p2)
(cheaper p1 p2
finish)))
(rest queue))))))
最後に、「コスト」関数と「安価」関数を次に示します。
(defun cost (path)
(apply '+ (mapcar #'(lambda (x) (get x 'cost)) path)))
(defun cheaper (p1 p2)
(< (cost p1)
(cost p2)))
編集:申し訳ありませんが、ここに「拡張」があります:
(defun extend (path)
(print (reverse path))
(mapcar #'(lambda (new-node) (cons new-node path))
(remove-if #'(lambda (neighbor) (member neighbor path))
(get (first path) 'neighbors))))