Advertisement
Guest User

Игра в восемь (Ларионов Д.С)

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