开发者

Lisp - Hill Climbing

开发者 https://www.devze.com 2023-03-01 18:55 出处:网络
Ok I have a Lisp implementation of BFS that I am trying to convert to do a hill climbing search. Here is what my BFS code looks like:

Ok I have a Lisp implementation of BFS that I am trying to convert to do a hill climbing search.

Here is what my BFS code looks like:

; The list of lists is the queue that we pass BFS.  the first entry and 
; every other entry in the queue is a list.  BFS uses each of these lists and 
; the path to search.  

(defun shortest-path (start end net)   
  (BFS end (list (list start)) net))

;We pass BFS the end node, a queue containing the starting node and the graph 
;being searched(net)   

(defun BFS (end queue net)
  (if (null queue) ;if the queue is empty BFS has not found a path so exit
      nil
      (expand-queue end (car queue) (cdr queue) net)))

(defun expand-queue (end path queue net)
  (let ((node (car path)))
    (if (eql node end)   ; If the current node is the goal node then flip the path
                         ; and return that as the answer
        (reverse path)
        ; otherwise preform a new BFS search by appending the rest of 
        ; the current queue to the result of the new-paths function
        (BFS end (append queue (new-path开发者_如何学Gos path node net)) net))))

; mapcar is called once for each member of the list new-paths is passed
; the results of this are collected into a list
(defun new-paths (path node net)
  (mapcar #'(lambda (n) (cons n path))
         (cdr (assoc node net))))

Now, I know that instead of always expanding the left node as I do in the BFS I need to expand the node that seems closest to the goal state.

The graph I am using looks like this:

(a (b 3) (c 1))  
(b (a 3) (d 1))

I have a conversion function to make this work with the above BFS implementation, but now I need to turn this into Hill climbing using this graph format.

I'm just not sure where to begin, and have been trying things to no avail. I know I mainly need to change the expand-queue function to expand the closest node, but I can't seem to make a function to determine which node is closest.

Thanks for the help!


Appending things to the end of a list is wrong. This is the most costly operation with a list. The whole list gets copied and then the other list is appended. You use it in a recursive procedure, which means that it will done each time you expand a node to create new paths.

If you put items on a queue, you need to look in which order you are doing this. With breadth first, one visits each node in a level, before moving to the next level. Hill-climbing would require that you sort the candidates for the 'best' by using a weighting function. So you need some kind of function computing a numeric value from a current node and the next node candidate. Then you need to sort the candidates and expand first the 'best' node. For a LIFO (last in, first out) queue this means that the most promising node needs to be pushed last, so that it will be the first to be expanded. Note that LIFO queues are a good fit for singly linked lists. FIFO (first in, first out) not so.

A typical idea of computer science is data abstraction. If a LIFO QUEUE is such a data structure, you need to define functions like MAKE-LIFO-QUEUE, EMPTY-QUEUE-P, ... Theses functions you would then use instead of LIST, NULL and others and they make the purpose of the data structure clearer. This makes your code longer, but since Lisp lists are generic and can be (ab-)used for all kinds of usage scenarios, looking at list operations alone does not make their intention clear. Especially important is this for more complicated graph algorithms.

0

精彩评论

暂无评论...
验证码 换一张
取 消