2017-02-06 3 views
0

enter image description here이미지의지도로 두 도시의 x와 y

내가 혀짤배기 배우려고 노력하고 코드 위의 문제 사이의 거리를 계산하는 리스프 기능을 구현합니다. 나는 그것이 작동하는 방법을 이해하기 위해 아래의 aima 코드를 살펴 보았다.

enter image description here

어떤 사람이 나를 이해하는 데 도움 주실 래요

내가 잘못 갈거야 :하지만 아래의 오류는 무엇입니까?

;;; -*- Mode: Lisp; Syntax: Common-Lisp; -*- File: search/domains/route-finding 

;;;; Find a Route Between Cities on a Map 

(defun route-finding-problem (&key (n-cities 10) 
        (map (random-route-map :n-cities n-cities)) 
        (start (city-name (random-element map))) 
        (goal (city-name (random-element map)))) 
    "Create a route-finding problem, using a random map, unless you explicitly 
    specify the :map argument." 
    (let ((goal-city (find-city goal map))) 
    (make-problem 
    :initial-state start 
    :successor-fn #'(lambda (x) (route-finding-successors x map)) 
    :goal-test  #'(lambda (x) (equal x goal)) 
    :h-cost-fn  #'(lambda (x) 
      (straight-distance (find-city x map) goal-city)) 
    :edge-cost-fn #'(lambda (x y) 
      (road-distance (find-city x map) y map)) 
    :domain   "Route Finding" 
    ))) 

;;; We define two data structures in this file: 
;;;  city - A structure holding a name, location, and neighbors 
;;;  map - A list of cities 
;;; A state in a route-finding problem is just the name of the current 
;;; city. We can use this name to lookup on a map and find a city 
;;; structure, which contains the cities location (an (x y) pair) and 
;;; a list of neighboring cities, and the distance along the road to 
;;; each neighbor. Be careful to distinguish between a city name and 
;;; a city structure. Note that a more complicated version of this 
;;; problem would augment the state with considerations of time, gas 
;;; used, wear on car, tolls to pay, etc. 

(defstruct (city (:type list)) 
    name loc neighbors) 

(defun route-finding-successors (city-name map) 
    "Return a list of (action . new-state) pairs. 
    In this case, the action and the new state are both the name of the city." 
    (with-collection() 
    (for each pair in (city-neighbors (find-city city-name map)) do 
    (collect (cons (first pair) (first pair)))))) 

(defun road-distance (city1 city-name2 map) 
    "The distance along the road between two cities. The first is a city 
    structure, the second just the name of the intended destination." 
    (declare (ignore map)) 
    (cdr (assoc city-name2 (city-neighbors city1)))) 

(defun straight-distance (city1 city2) 
    "Distance between two cities on a straight line (as the crow flies)." 
    ;; We round this to the nearest integer, just to make things easier to read 
    (round (xy-distance (city-loc city1) (city-loc city2)))) 

(defun find-city (name map) 
    "Look up the city on the map, and return its information." 
    (assoc name map)) 

(defun random-route-map (&key (n-cities 10) (width 100) (height 100) 
        (min-roads 2) (max-roads (+ min-roads 3))) 
    "Return a random map with n-cities in it, and some roads between them. 
    Each city is connected to between MIN-ROADS and MAX-ROADS other cities. 
    The default is from 2 to 5. The road between any two cities has a length 
    of 1 to 1.5 times the straight-line distance between them." 
    ;; First build the cities 
    (let ((map (with-collection() 
      (for i = 1 to n-cities do 
      (collect 
      (make-city :name (number->name i) :neighbors nil 
        :loc (@ (random width) (random height)))))))) 
    ;; Now lay down the roads 
    ;; CANDIDATES is all the cities that don't yet have a road to CITY 
    ;; SORTED-NEIGHBORS is sorted by distance to CITY, closest first 
    ;; We pick out the first 
    (for each city in map do 
    (let* ((n-roads (- (random-integer min-roads max-roads) 
       (length (city-neighbors city)))) 
     (candidates 
     (remove-if #'(lambda(c) 
       (or (eq c city) 
        (assoc (city-name c) 
         (city-neighbors city)))) 
       map)) 
     (sorted-neighbors 
     (sort candidates #'< 
       :key #'(lambda (city2) 
       (straight-distance city city2))))) 
     (for each city2 in (subseq sorted-neighbors 0 (max n-roads 0)) do 
     (build-road city city2)))) 
    map)) 

(defun build-road (city1 city2) 
    "Construct a road between two cities." 
    (let* ((distance (straight-distance city1 city2)) 
    (road-distance (round (* (+ 1.0 (random 0.5)) distance)))) 
    (push (cons (city-name city1) road-distance) (city-neighbors city2)) 
    (push (cons (city-name city2) road-distance) (city-neighbors city1)))) 

(defun number->name (i) 
    "Turn an integer into a symbol. 1-26 go to A-Z; beyond that use Ci" 
    (if (<= 1 i 26) 
     (aref '#(0 a b c d e f g h i j k l m n o p q r s t u v w x y z) i) 
    (intern (format nil "C~D" i)))) 

;;;; The Romanian Map 

(defparameter *romania-map* 
    '(
    (Arad  (91 492) ((Zerind . 75) (Sibiu . 140) (Timisoara . 118))) 
    (Bucharest (400 327) ((Fagaras . 211) (Pitesti . 101) (Giurgiu . 90) 
       (Urziceni . 85))) 
    (Craiova (253 288) ((Dobreta . 120) (Rimnicu . 146) (Pitesti . 138))) 
    (Dobreta (165 299) ((Mehadia . 75) (Craiova . 120))) 
    (Eforie (562 293) ((Hirsova . 86))) 
    (Fagaras (305 449) ((Sibiu . 99) (Bucharest . 211))) 
    (Giurgiu (375 270) ((Bucharest . 90))) 
    (Hirsova (534 350) ((Urziceni . 98) (Eforie . 86))) 
    (Iasi (473 506) ((Neamt . 87) (Vaslui . 92))) 
    (Lugoj (165 379) ((Timisoara . 111) (Mehadia . 70))) 
    (Mehadia (168 339) ((Lugoj . 70) (Dobreta . 75))) 
    (Neamt (406 537) ((Iasi . 87))) 
    (Oradea (131 571) ((Zerind . 71) (Sibiu . 151))) 
    (Pitesti (320 368) ((Rimnicu . 97) (Craiova . 138) (Bucharest . 101))) 
    (Rimnicu (233 410) ((Sibiu . 80) (Pitesti . 97) (Craiova . 146))) 
    (Sibiu (207 457) ((Arad . 140) (Oradea . 151) (Fagaras . 99) 
       (Rimnicu . 80))) 
    (Timisoara (94 410) ((Arad . 118) (Lugoj . 111))) 
    (Urziceni (456 350) ((Bucharest . 85) (Hirsova . 98) (Vaslui . 142))) 
    (Vaslui (509 444) ((Iasi . 92) (Urziceni . 142))) 
    (Zerind (108 531) ((Arad . 75) (Oradea . 71))) 
    ) 
    "A representation of the map in Figure 4.2 [p 95]. 
    But note that the straight-line distances to Bucharest are NOT the same.") 

(defun romanian-problem (&key (start 'Arad) (goal 'Bucharest)) 
    "Problem: Find a path between two cities in Romania." 
    (route-finding-problem :start start :goal goal :map *romania-map*)) 

(defun random-romanian-problem() 
    "Problem: Find a path between two random cities in Romania." 
    (romanian-problem :start (city-name (random-element *romania-map*)) 
      :goal (city-name (random-element *romania-map*)))) 

답변

1

임의 요소 기능을 정의하지 않은 것으로 보입니다!

은 다음과 같이 그것을 정의하는 것을 시도 : 당신이 정말 좋아하지만 Peter Norvig's book에서 예를 사용하고 난 당신이 원하는 경우 첫 번째 책으로 고려하지 않을 것 같은

(defun random-element (list) 
    "Return some element of the list, chosen at random." 
    (nth (random (length list)) list)) 
+0

답장을 보내 주셔서 감사합니다. 그러나 두 도시 사이의 거리를 어떻게 알 수 있습니까? – user6622569

0

그것은 나에게 보인다 Common Lisp을 배우는 법. Wiki에서 'common-lisp'태그에 대한 초보자를위한 조언을 찾을 수 있습니다.

그럼에도 불구하고 PAIP의 example source code에는 찾고자하는 기능인 distance이 있습니다.