(defstruct city name neighbors h visited) (defvar *acl* nil) (defvar *acht* (make-hash-table)) (defun set-neighbors (city neighbors) (loop for nei in neighbors do (setf (city-neighbors city) (push nei (city-neighbors city))))) (defun set-neighbors-from-namelist (city namelist) (loop for name in namelist do (setf (city-neighbors city) (push (get-city-from-list name) (city-neighbors city))))) ;(defun read-file (file) ; (with-file-open (in file) ; (read in))) (defun read-file (path-to-file) (with-open-file (s path-to-file) (read s))) ;(defun read-file (filename) ; (with-open-file (stream filename) ; (loop for line = (read-line stream nil) ; while line ; collect line))) (defun setup-cities (file) (setf str (read-file file)) (setf cities (loop for city in str collect (make-city :name (car city) :neighbors nil :h (cadr city)) ) ) (setf *acl* cities) (loop for current in str for city in *acl* do (set-neighbors-from-namelist city (caddr current)) ) ) (defvar *city1* (make-city :name "Bucharest" :neighbors nil :h 0)) (defvar *city2* (make-city :name "Pitesti" :neighbors nil :h 100)) (defvar *city3* (make-city :name "Rimnicu Vilcea" :neighbors nil :h 193)) (defvar *city4* (make-city :name "Sibiu" :neighbors nil :h 253)) (defvar *city5* (make-city :name "Fagaras" :neighbors nil :h 176)) (set-neighbors *city1* (list (list *city2* 101) (list *city5* 211))) (set-neighbors *city2* (list (list *city1* 101) (list *city3* 97))) (set-neighbors *city3* (list (list *city2* 97) (list *city4* 80))) (set-neighbors *city4* (list (list *city3* 80) (list *city5* 99))) (set-neighbors *city5* (list (list *city1* 211) (list *city4* 99))) (setf *acl* (push *city1* *acl*)) (setf *acl* (push *city2* *acl*)) (setf *acl* (push *city3* *acl*)) (setf *acl* (push *city4* *acl*)) (setf *acl* (push *city5* *acl*)) (setf (gethash '1 *acht*) *city1*) (setf (gethash '2 *acht*) *city2*) (setf (gethash '3 *acht*) *city3*) (setf (gethash '4 *acht*) *city4*) (setf (gethash '5 *acht*) *city5*) (defun city-print (city) (print (format nil "City Name: ~D" (string (city-name city)))) (print (format nil "Neighbors:")) (loop for nei in (city-neighbors city) do (print (format nil "~D: ~D miles away" (city-name (car nei)) (cadr nei))) ) (print (format nil "Distance to Bucharest: ~D~%" (city-h city)))) (defun all-cities-from-list (cities) (loop for cit in cities collect (city-name cit))) (defun all-cities-from-htable (cities) (loop for value being the hash-values of cities collect value)) (defun get-city-from-list (cname) ;Take city name, return corresponding structure (loop for cit in *acl* do (if (equalp (city-name cit) cname) (return-from get-city-from-list cit)))) (defun get-city-from-htable (cname) ;Take city name, return corresponding structure (loop for value being the hash-values of *acht* do (if (equalp (city-name value) cname) (return-from get-city-from-htable value)))) (defun neighbors-using-list (cname) ;Take city name, return list of neighbor structures ;NOTE: Returns the ASSOCIATED LIST FORM (structure, dist) (setf city (get-city-from-list cname)) (loop for nei in (city-neighbors city) collect nei)) (defun neighbors-using-htable (cname) ;Take city name, return list of neighbor structures ;NOTE: Returns the ASSOCIATED LIST FORM (structure, dist) (setf city (get-city-from-htable cname)) (loop for nei in (city-neighbors city) collect nei)) (defun neighbors-within-d (my-city distance) ;Take city name, return list of all direct neighbors within the given distance (inclusive). (setf neighbors (neighbors-using-list (city-name my-city))) (loop for nei in neighbors when (<= (cadr nei) distance) collect (car nei) ) ) (defun neighbors-p (cn1 cn2) ;Takes two city names, returns distance between if neighbors (nil if not). (setf c1 (get-city-from-list cn1)) (setf c2 (get-city-from-list cn2)) (loop for nei in (city-neighbors c1) do (if (equalp c2 (car nei)) (return-from neighbors-p (cadr nei)) ) ) ) (defstruct node city parent children path cost) ;Path is a list of city NAMES, starting with root and ending with itself. (defun get-node-from-nodelist (city) (loop for node in *nodelist* do (if (equal (node-city node) city) (return-from get-node-from-graph node) ) ) nil) (defun evaluate-node-g (node) (do ( (path (node-pathval node) (rest path)) (temp 0 (+ temp (neighbors-p (car path) (cadr path)))) ) ((not (cadr path)) temp))) (defun evaluate-fringe (fringe) (let (result resultDist) (setf resultDist 999999999) (if (not fringe) (print "FRINGE IS EMPTY") ) (loop for node in fringe do (if (< (evaluate-node-g node) resultDist) (setf result node) ) do (if (< (evaluate-node-g node) resultDist) (setf resultDist (evaluate-node-g node)) ) ) result ) ) (defun print-node (node) (print (format nil "City: ~D" (string (city-name (node-city node))))) (print (format nil "Parent: ~D" (string (city-name (node-city (node-parent node)))))) (print (format nil "Children: ")) (loop for ch in (node-children node) do (print (format nil "~D" (city-name (node-city ch)))) ) (print (format nil "Path: ~S" (node-path node))) (print (format nil "Cost: ~D" (node-cost node))) ) (defun expand-node (node) (let (result) ;(print "test a") (setf (city-visited (node-city node)) t) ;(print "test b") (loop for nei in (city-neighbors (node-city node)) do (print "howdy") do (setf tn (make-node :city (car nei) :parent node :children nil :path (append (node-path node) (city-name (car nei))) :cost (+ (node-cost node) (cadr nei)) ) ) do(print-node tn) do (if (not (city-visited (car nei))) (setf result (append result tn)) ) do (if (not (city-visited (car nei))) (print "APPENDED A CITY") ) do (setf (node-children node) (append (node-children node) tn)) do(print "test e") do (if (not result) (print "AAAAAAAAA")) ) (loop for nd in result do (print-node nd) ) (if (not result) (print "AAAAAAAAA")) result ) ) (defun bfs (cname) (let (node fringe) (print "test 1") (setf node (make-node :city (get-city-from-list cname) :parent nil :children nil :path (list cname) :cost 0 )) (print "test 2") (do ;vars () ;condition ((equal (city-name (node-city node)) "Bucharest") (return-from bfs "FK:LSJDF:LKDSJF:LKSD")) ;body (print "test 3") (setf fringe (append fringe (expand-node node))) (print "test 4") (setf node (evaluate-fringe fringe)) (print "test 5") ) ) ;lookup node, set as current ;expand ;append results to fringe ;evaluate fringe to get node ;check if node is goal ;if not expand ) (bfs "Sibiu") ;BFS - choose lowest g ;expand-node - takes node, returns list of its children ;evaluate-fringe - take list of nodes, returns node to be expanded ;evaluate-node - takes node, provides g (used by evaluate-fringe) ;call expand-node ;append its results to the fringe ;call evaluate-fringe on the fringe ;check if result is goal ;if not, call expand node on it (all-cities-from-list *acl*) (all-cities-from-list (all-cities-from-htable *acht*)) (print (neighbors-p "Bucharest" "Fagaras")) ;(setup-cities "all-cities.lisp")
We use cookies to provide and improve our services. By using our site, you consent to our Cookies Policy. Accept Learn more