Advertisement
Guest User

Игра в восемь (Поиск в ширину с эвристикой) (Д.С Ларионов)

a guest
Dec 10th, 2017
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;;;Ввод
  2. (defvar *start* '(1 0 2
  3.                   3 4 5
  4.                   6 7 8)
  5. )
  6.  
  7. (defvar *goal* '(0 1 2
  8.                  3 4 5
  9.                  6 7 8)
  10. )
  11.  
  12. ;;; Матрица смежности (возможных перемещений для каждой позиции "пустой" панели)
  13.  
  14. (defvar *adj*
  15.     '((0 1 3)
  16.       (1 0 4 2)
  17.       (2 1 5)
  18.       (3 0 4 6)
  19.       (4 1 3 5 7)
  20.       (5 2 4 8)
  21.       (6 3 7)
  22.       (7 4 6 8)
  23.       (8 5 7))
  24. )
  25.  
  26.  
  27. (defun goalp (state)
  28.     (equal state  *goal*)
  29. )
  30.  
  31. (defun transpose (state i j)
  32.     (transpose1 state j i (nth i state) (nth j state))
  33. )
  34.  
  35. (defun transpose1 (state i j ival jval)
  36.     (cond
  37.     ((null state) nil)
  38.     ((zerop i)
  39.         (cons ival
  40.         (transpose1 (cdr state) (- i 1) (- j 1) ival jval)))
  41.     ((zerop j)
  42.         (cons jval
  43.         (transpose1 (cdr state) (- i 1) (- j 1) ival jval)))
  44.     (t
  45.         (cons (car state)
  46.         (transpose1 (cdr state) (- i 1) (- j 1) ival jval))))
  47. )
  48.  
  49. (defun loc-of (num state)
  50.     (cond
  51.     ((null state) 0)
  52.     ((eq (car state) num) 0)
  53.     ((+ 1 (loc-of num (cdr state)))))
  54. )
  55.  
  56. (defun space-at (state)
  57.     (loc-of 0 state)
  58. )
  59.  
  60. (defun new-states (state)
  61.     (let ((zloc (space-at state)))
  62.     (mapcar #'(lambda (toloc)
  63.               (transpose state zloc toloc))
  64.         (cdr (assoc zloc *adj*))))
  65. )
  66.  
  67.  
  68. ;;; Cчитаем эвристику для переденного состояния игры
  69.  
  70. (defun heur-value (state)
  71.     (+
  72.     (* 3 (similarity state *goal*))
  73.     (adj-value state *goal*))
  74. )
  75.  
  76. ;;; Число пластинок, находящихся в идентичных позициях в двух состояниях
  77. (defun similarity (s1 s2)
  78.     (cond
  79.     ((or (null s1) (null s2)) 0)
  80.     ((equal (car s1) (car s2))
  81.         (+ 1 (similarity (cdr s1) (cdr s2))))
  82.     ((similarity (cdr s1) (cdr s2))))
  83. )
  84.  
  85. (defun adj-num (num state)
  86.     (mapcar
  87.     #'(lambda (n) (nth n state))
  88.     (cdr (assoc (loc-of num state) *adj*)))
  89. )
  90.  
  91. (defun number-common (l1 l2)
  92.     (cond
  93.     ((null l1) 0)
  94.     ((null l2) 0)
  95.     ((intersection (list (car l1)) l2)
  96.         (+ 1 (number-common (cdr l1) l2)))
  97.     ((number-common (cdr l1) l2)))
  98. )
  99.  
  100. ;;; Число идентичных значений смежности для двух состояний
  101. (defun adj-value (s1 s2)
  102.     (apply #'+
  103.     (mapcar
  104.         #'(lambda (num)
  105.           (number-common (adj-num num s1) (adj-num num s2)))
  106.         '(1 2 3 4 5 6 7 8)))
  107. )
  108.  
  109.  
  110. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  111.  
  112. ;; Ведем поиск в ширину
  113. (defun hval-of (node) (car node))
  114. (defun state-of (node) (cadr node))
  115. (defun path-of (node) (cdr node))
  116. (defun depth-of (node) (length (cddr node)))
  117.  
  118. (defvar *visited* nil)
  119. (defvar *heur-mult* 2)
  120.  
  121. (defun best (state limit)
  122.     (let ((nodes 0)
  123.          (expanded 0)
  124.          (branches 0)
  125.          (limit limit)
  126.          (open (list (list (heur-value state) state))))
  127.  
  128.     (setf *visited* nil)
  129.    
  130.     (loop
  131.         (cond ((null open)
  132.               (print (list 'nodes nodes expanded branches))
  133.               (return (list 'no 'solution 'found))))
  134.        
  135.         (incf nodes)
  136.        
  137.         (cond ((goalp (state-of (car open)))
  138.               (print (list 'nodes nodes expanded branches))
  139.               (print (list 'length 'of 'soln (depth-of (car open))))
  140.               (return (path-of (car open)))))
  141.        
  142.         (cond ((> nodes limit)
  143.               (print (list 'nodes nodes expanded branches))
  144.               (return (list 'closest 'was (car open)  ))))
  145.        
  146.         (let ((children (new-states (state-of (car open)))))
  147.         (incf expanded)
  148.         (setf branches (+ (length children) branches))
  149.         (setf open (combine-queue children (car open) (cdr open))))))
  150. )
  151.  
  152. ;;; Получаем непосещенные ещё вершины
  153.  
  154. (defun combine-queue (new-states node queue)
  155.     (push (state-of node) *visited*)
  156.     (dolist (state new-states)
  157.     (if (not (member state *visited* :test #'equal))
  158.         (push (cons (- (* *heur-mult* (heur-value state)) (depth-of node))
  159.               (cons state (cdr node)))
  160.         queue)))
  161.     (sort queue #'> :key #'car)
  162. )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement