;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; PROGRAMA QUE IMPLEMENTA UNA BUSQUEDA GENERAL ;; ;; Autor: Ing. J. Rafael R. Ochoa ;; ;; Materia: SISTEMAS EXPERTOS ;; ;; MAESTRIA EN SISTEMAS COMPUTACIONALES ;; ;; ;; Noviembre 1997 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun carga () (load "c:\\rafa\\busqueda.lsp")) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; el comienzo del juego de los ;; 8 cuadritos. ;; Regresa: Las fichas que se encuentran ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun juego () (print "Ingrese los elementos que componen el tablero") (print "Se trata de 8 fichas (1 - 8) y un espacio en") (print "blanco (B) Cada uno de los tres renglones consta") (print "de tres elementos separados por un ENTER") (setq inicio (forma_arreglo)) (print "Ahora dame las posiciones finales de las fichas") (setq final (forma_arreglo)) (print "Las fichas que se encuentran en posicion equivocada son: ") (checa_posicion inicio final) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Funciones: FORMA_ARREGLO y PREGUNTA ;; ya sea el arreglo inicial ;; como el final ;; Regresa: Un nuevo ARREGLO DE 3x3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun forma_arreglo () (setq x 0) (setq arreglo (make-array '(3 3))) (loop (if (eq x 3) (return arreglo)) (format t "~%Renglon ~a: " (+ x 1)) (setq y 0) (loop (if (eq y 3) (return)) (setf (aref arreglo x y) (pregunta)) (setq y (1+ y))) (setq x (1+ x)))) (defun pregunta () (read)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Recibe: Un ARREGLO inicial => "a_i" y un ;; ARREGLO final (goal) => "a_f" ;; Proposito: Determinar la cantidad de ;; Regresa: Un NUMERO ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun checa_posicion (a_i a_f) (setq x 0) (setq mal 0) (loop (if (eq x 3) (return mal)) (setq y 0) (loop (if (eq y 3) (return)) (if (not (equal (aref a_i x y) (aref a_f x y))) (setq mal (1+ mal))) (setq y (1+ y))) (setq x (1+ x)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Recibe: Un arreglo => "arreglo" ;; del "blanco" ;; Regresa: Una LISTA DE DOS ELEMENTOS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun busca-blanco (arreglo) (dolist (i '(0 1 2)) (dolist (j '(0 1 2)) (if (eq (aref arreglo i j) 'b) (return-from busca-blanco (list i j)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Recibe: Un arreglo => "arreglo" ;; Proposito: Determinar los movimientos ;; disponibles de acuerdo a la ;; Regresa: Una LISTA con los movimientos ;; permitidos ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun genera-mvtos (arreglo) (let ((loc (busca-blanco arreglo))) (cond ((equal loc '(0 0)) '(l u)) ((equal loc '(0 1)) '(r l u)) ((equal loc '(0 2)) '(r u)) ((equal loc '(1 0)) '(d l u)) ((equal loc '(1 1)) '(l r u d)) ((equal loc '(1 2)) '(d r u)) ((equal loc '(2 0)) '(d l)) ((equal loc '(2 1)) '(l d r)) ((equal loc '(2 2)) '(d r))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; => "loc-b" y el sentido del ;; movimiento (una LETRA) => "dir" ;; Regresa: Una LISTA con la ficha a mover ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun quien-mueve? (loc-b dir) (cond ((equal dir 'r) (list (first loc-b) (1- (second loc-b)))) ((equal dir 'l) (list (first loc-b) (1+ (second loc-b)))) ((equal dir 'u) (list (1- (first loc-b)) (second loc-b))) ((equal dir 'd) (list (1+ (first loc-b)) (second loc-b))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Recibe: Un arreglo => "arreglo" y la ;; Proposito: Ejecuta el swap ;; Regresa: Un nuevo ARREGLO con una nueva ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun mueve (arreglo dir) (let* ((loc-b (busca-blanco arreglo)) (quien (quien-mueve? loc-b dir)) (nvo-arreglo (make-array '(3 3))) (renglon 0) (columna 0)) (loop (setq columna 0) (loop (setf (aref nvo-arreglo renglon columna) (aref arreglo renglon columna)) (incf columna) (when (eq columna 3) (return))) (incf renglon) (when (eq renglon 3) (return))) (rotatef (aref nvo-arreglo (first loc-b) (second loc-b)) (aref nvo-arreglo (first quien) (second quien))) nvo-arreglo)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Recibe: Un arreglo => "arreglo" ;; Regresa: Una LISTA DE ARREGLOS con todos ;; las posibilidades de movimientos ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun expand (arreglo) (let* ((movimientos (genera-mvtos arreglo))) (mapcar #'(lambda (dir) (mueve arreglo dir)) movimientos))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;busqueda_general (problema estrategia fn) ;; nodos=estado_inicial(problema) ;; loop ;; if empty(nodos) return fail ;; nodo=estrategia(nodos) ;; if goal(nodo) return nodo ;; else nodos=fn(nodos,expand(nodo)) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;BFS (problema) ;; return busqueda_general(problema,primero,append) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;