Anexo 5 - Dpto. Ciencias de la Computación e Inteligencia Artificial

Anuncio
Anexo 5: Implementaciones en Lisp
José A. Alonso Jiménez
Carmen Graciani Dı́az
Francisco Jesús Martı́n Mateos
José Luis Ruiz Reina
Dpto. Ciencias de la Computación e Inteligencia Artificial
U NIVERSIDAD
IIA 2004-05
C c Ia
DE
S EVILLA
Implementaciones en Lisp
A5.1
Representación de PSRs
• Representación de las variables:
(defstruct (variable-psr (:constructor crea-variable)
(:conc-name psr-var-))
nombre
dominio)
• Representación de las restricciones:
(defstruct (restriccion-psr (:constructor crea-restriccion)
(:conc-name psr-restr-))
variables
funcion)
IIA 2004-05
C c Ia
Implementaciones en Lisp
A5.2
N reinas
(defun crea-dominio (n) (loop for i from 1 to n collect i))
(defun n-reinas (n)
(defparameter *variables*
(loop for i from 1 to n collect
(crea-variable :nombre i :dominio (crea-dominio n))))
(defparameter *restricciones*
(loop for i from 1 to n append
(loop for j from 1 to n
when (> j i)
collect (crea-restriccion
:variables (list i j)
:funcion (restriccion-reinas i j))))))
(defun restriccion-reinas (i j)
#’(lambda (x y)
(and (not (= x y))
(not (= (abs (- x y)) (abs (- i j)))))))
IIA 2004-05
C c Ia
Implementaciones en Lisp
A5.3
Colorear el mapa de Andalucía (I)
(defparameter *colores* ’(azul rojo verde))
(defparameter *variables*
(list (crea-variable :nombre
(crea-variable :nombre
(crea-variable :nombre
(crea-variable :nombre
(crea-variable :nombre
(crea-variable :nombre
(crea-variable :nombre
(crea-variable :nombre
IIA 2004-05
’Huelva :dominio *colores*)
’Sevilla :dominio *colores*)
’Cadiz :dominio *colores*)
’Malaga :dominio *colores*)
’Cordoba :dominio *colores*)
’Jaen :dominio *colores*)
’Granada :dominio *colores*)
’Almeria :dominio *colores*)))
C c Ia
Implementaciones en Lisp
A5.4
Colorear el mapa de Andalucía (II)
(defun distintos (x y)
(not (eq x y)))
(defparameter *restricciones*
(list (crea-restriccion :variables
(crea-restriccion :variables
(crea-restriccion :variables
(crea-restriccion :variables
(crea-restriccion :variables
(crea-restriccion :variables
(crea-restriccion :variables
(crea-restriccion :variables
(crea-restriccion :variables
(crea-restriccion :variables
(crea-restriccion :variables
IIA 2004-05
C c Ia
’(Huelva Sevilla) :funcion #’distintos))
’(Huelva Cadiz) :funcion #’distintos))
’(Cadiz Malaga) :funcion #’distintos))
’(Cadiz Sevilla) :funcion #’distintos))
’(Sevilla Cordoba) :funcion #’distintos))
’(Sevilla Malaga) :funcion #’distintos))
’(Cordoba Jaen) :funcion #’distintos))
’(Cordoba Malaga) :funcion #’distintos))
’(Malaga Granada) :funcion #’distintos))
’(Granada Jaen) :funcion #’distintos))
’(Granada Almeria) :funcion #’distintos))
Implementaciones en Lisp
A5.5
Búsqueda en profundidad (I)
• Estados finales:
(defun es-asignacion-completa (estado)
(= (length estado) (length *variables*)))
• Sucesores:
(defun bpr-sucesores (actual)
(elimina-inconsistentes-nueva-asignacion
(asigna-nueva-variable actual)))
IIA 2004-05
C c Ia
Implementaciones en Lisp
A5.6
Búsqueda en profundidad (II)
• Asignación de nuevas variables:
(defun asignada (variable estado)
(assoc variable estado))
(defun primera-variable-no-asignada (estado)
(find-if-not
#’(lambda (x) (asignada (psr-var-nombre x) estado))
*variables*))
(defun asigna-nueva-variable (estado)
(let* ((variable (primera-variable-no-asignada estado))
(nombre (psr-var-nombre variable))
(dominio (psr-var-dominio variable)))
(loop for val in dominio collect (acons nombre val estado))))
IIA 2004-05
C c Ia
Implementaciones en Lisp
A5.7
Búsqueda en profundidad (III)
• Eliminación de asignaciones inconsistentes:
(defun elimina-inconsistentes-nueva-asignacion (estados)
(loop for estado in estados
when (verifica-restricciones-posibles estado)
collect estado))
(defun verifica-restricciones-posibles (estado)
(loop for restriccion in *restricciones*
always
(let* ((variables (psr-restr-variables restriccion))
(a1 (assoc (first variables) estado))
(a2 (assoc (second variables) estado)))
(or (not (member (caar estado) variables))
(not a1) (not a2)
(funcall (psr-restr-funcion restriccion) (cdr a1) (cdr a2))))))
IIA 2004-05
C c Ia
Implementaciones en Lisp
A5.8
Búsqueda en profundidad (y IV)
• Búsqueda en profundidad:
(defun psr-busqueda-en-profundidad ()
(let ((abiertos (list nil)))
(loop until (null abiertos) do
(setf actual (first abiertos))
(setf abiertos (rest abiertos))
(cond ((es-asignacion-completa actual)
(return actual))
(t (setf nuevos-sucesores (bpr-sucesores actual))
(setf abiertos (append nuevos-sucesores abiertos)))))))
IIA 2004-05
C c Ia
Implementaciones en Lisp
A5.9
Consistencia de arcos
• Arco = Restricción + Variable
(defstruct (arco (:constructor crea-arco)
(:conc-name arco-))
variable
restriccion)
• Lista de arcos de un P.S.R.:
(defun arcos ()
(loop for restriccion in *restricciones* append
(loop for var in (psr-restr-variables restriccion) collect
(crea-arco :variable var :restriccion restriccion))))
IIA 2004-05
C c Ia
Implementaciones en Lisp
A5.10
Algoritmo de consistencia de arcos AC-3
(defun ac3 (variables)
(let ((red (arcos))
(actual nil))
(loop until (null red) do
(setf actual (first red))
(setf red (rest red))
(let* ((variable-mod
(variable-nombre (arco-variable actual) variables))
(restriccion (arco-restriccion actual))
(viejo-dominio (psr-var-dominio variable-mod))
(nuevo-dominio
(actualiza-dominio variable-mod variables restriccion)))
(when (not (equal nuevo-dominio viejo-dominio))
(setf (psr-var-dominio variable-mod) nuevo-dominio)
(when (null nuevo-dominio) (return))
(setf red (append red (nuevos-arcos variable-mod red)))))))
variables)
IIA 2004-05
C c Ia
Implementaciones en Lisp
A5.11
Algoritmo de consistencia de arcos AC-3
• Obtención de arcos cuya consistencia es discutible:
(defun nuevos-arcos (variable-mod red)
(let ((var-mod (psr-var-nombre variable-mod))
(arcos (arcos)))
(loop for arco in arcos
when (and (not (equal var-mod (arco-variable arco)))
(not (member arco red :test #’equalp))
(member var-mod (psr-restr-variables
(arco-restriccion arco))))
collect arco)))
IIA 2004-05
C c Ia
Implementaciones en Lisp
A5.12
Algoritmo de consistencia de arcos AC-3
• Actualización de dominios (restricciones binarias):
(defun actualiza-dominio (variable-mod variables restriccion)
(let ((nombre1 (first (psr-restr-variables restriccion)))
(nombre2 (second (psr-restr-variables restriccion)))
(funcion (psr-restr-funcion restriccion)))
(cond ((equal (psr-var-nombre variable-mod) nombre1)
(loop for val1 in (psr-var-dominio variable-mod) when
(test-de-existencia-1 val1
(variable-nombre nombre2 variables)
funcion)
collect val1))
(t (loop for val2 in (psr-var-dominio variable-mod) when
(test-de-existencia-2 val2
(variable-nombre nombre1 variables)
funcion)
collect val2)))))
IIA 2004-05
C c Ia
Implementaciones en Lisp
A5.13
Algoritmo de consistencia de arcos AC-3
• Tests de existencia:
(defun test-de-existencia-1 (val1 var2 funcion)
(loop for val2 in (psr-var-dominio var2)
thereis (funcall funcion val1 val2)))
(defun test-de-existencia-2 (val2 var1 funcion)
(loop for val1 in (psr-var-dominio var1)
thereis (funcall funcion val1 val2)))
IIA 2004-05
C c Ia
Implementaciones en Lisp
A5.14
Búsqueda mediante consistencia de arcos
• Búsqueda por consistencia de arcos:
(defun busqueda-ac3 ()
(let ((abiertos (list (copia-lista-variables-psr *variables*)))
(actual nil))
(loop until (null abiertos) do
(setf actual (ac3 (first abiertos)))
(setf abiertos (rest abiertos))
(cond ((hay-dominio-vacio actual)
nil)
((dominios-unitarios actual)
(return actual))
(t (setf abiertos
(append (cda-sucesores actual) abiertos)))))))
IIA 2004-05
C c Ia
Implementaciones en Lisp
A5.15
Búsqueda mediante consistencia de arcos
• Comprobación de dominios vacíos:
(defun hay-dominio-vacio (variables)
(loop for var in variables thereis (dominio-vacio var)))
• Generación de sucesores:
(defun cda-sucesores (estado)
(let* ((seleccion (selecciona-dominio estado))
(inicio (first seleccion))
(variable (second seleccion))
(final (third seleccion))
(nuevos-dominios (rompe-dominio variable)))
(loop for var in nuevos-dominios
collect (append (copia-lista-variables-psr inicio)
(list var)
(copia-lista-variables-psr final)))))
IIA 2004-05
C c Ia
Implementaciones en Lisp
A5.16
Búsqueda mediante consistencia arcos
• Seleccionar una variable con dominio no unitario:
(V1 . . . Vi . . . Vn ) =⇒ ((V1 . . . Vi−1 ) Vi (Vi+1 . . . Vn ))
(defun selecciona-dominio (variables)
(let ((indice (position-if-not #’dominio-unitario variables)))
(list (subseq variables 0 indice)
(nth indice variables)
(subseq variables (+ indice 1)))))
• Romper un dominio en subdominios (unitario más el resto):
(defun rompe-dominio (variable)
(list (crea-variable :nombre (psr-var-nombre variable)
:dominio (list (first (psr-var-dominio variable))))
(crea-variable :nombre (psr-var-nombre variable)
:dominio (rest (psr-var-dominio variable)))))
IIA 2004-05
C c Ia
Implementaciones en Lisp
A5.17
Descargar