Sie sind auf Seite 1von 18

Métodos para la solución de problemas.

2. Solución de problemas.

La solución de problemas es fundamental para la mayoría de las aplicaciones de IA;


existen principalmente dos clases de problemas que se pueden resolver mediante
procesos computables: aquéllos en los que se utiliza un algoritmo determinista que
garantiza la solución al problema y las tareas complejas que se resuelven con la búsqueda
de una solución; de ésta última clase de problemas se ocupa la IA.

2.1. Definición del problema como búsqueda en un espacio de estados.


En éste inciso se describe el esquema conocido como espacio de estados para representar
problemas.

Espacio de estados.
Un espacio de estados es un grafo cuyos nodos corresponden a estados del problema. De
éste modo, utilizando ésta representación, la solución a los problemas se convierte en la
búsqueda de caminos ó rutas óptimas dentro del grafo.

Representación de problemas mediante espacios de estados.


Estudiaremos ejemplos de formulación de problemas utilizando la aproximación de
espacio de estados.

El problema de los bloques.


El problema consiste en encontrar un plan para reordenar la pila de bloques que se
muestra en la figura 2.1

C A

A B

B C

Figura 2.1. El problema de los bloques.

las restricciones al problema son las siguientes: solamente podemos mover un bloque
cada vez; un bloque puede levantarse únicamente cuando no tiene nada encima; el bloque
levantado puede colocarse sobre el piso ó sobre otro bloque.
Fundamentos de Inteligencia Artificial 2

Para resolver el problema se requiere encontrar una secuencia de movimientos válidos


que hagan la conversión. Es decir, podemos entender el problema como una exploración
de alternativas posibles; en el estado inicial únicamente tenemos una alternativa: colocar
el bloque C sobre el piso. Luego del primer movimiento encontramos ahora tres
alternativas: poner el bloque A sobre el piso, colocar el bloque A sobre C y, poner el
bloque C sobre A.
Este tipo de análisis está basado en el manejo de dos tipos de conceptos: estados del
problema y, movimientos válidos que nos hagan pasar de un estado del problema a otro
estado del mismo.
El espacio de estados para este ejemplo se muestra en la figura 2.2.

C B
A A
B C

A A
BC BC

C B
B B C C
A AC ABC AB A

B C
AC AB

A A
B C
C B

Figura 2.2. Representación espacio-estado para el problema


de los bloques, indicando el camino de solución.

en ésta figura, los nodos corresponden a estados posibles del problema y los arcos
corrresponden a transiciones válidas entre estados posibles; el problema de encontrar un
plan de solución es equivalente a encontrar un camino entre un nodo inicial (estado
inicial) y un nodo meta (estado final).

FACULTAD DE MATEMATICAS
Fundamentos de Inteligencia Artificial 3

El rompecabezas de 8.
El problema consiste de una tabla de 3x3 celdas conteniendo ocho números del 1 al 8 y
una celda vacía. Como son ocho números, una celda siempre permanecerá vacía; un
número puede ‘moverse’ a una celda adyacente si ésta está vacía, dejando vacía la celda
donde se encontraba; el problema consiste en ordenar los números del 1 al 8 en forma
circular dejando la celda central vacía tal y como se muestra en la figura 2.3.

1 3 1 2 3
8 2 4 8 4
7 6 5 7 6 5

Figura 2.3. El rompecabezas de 8.

la representación espacio estado para éste problema es como sigue :

1 3
8 2 4
7 6 5

1 3 1 3 4
8 2 4 8 2
7 6 5 7 6 5

1 3 1 2 3 1 3 4 1 3 4
8 2 4 8 4 8 2 5 8 2
7 6 5 7 6 5 7 6 7 6 5

Figura 2.4. Representación espacio-estado para el problema


del rompecabezas de 8.

FACULTAD DE MATEMATICAS
Fundamentos de Inteligencia Artificial 4

El problema del juego de ajedrez.


Si queremos escribir un programa para jugar ajedrez, podríamos, en primer lugar,
especificar cuál es la posición inicial de las piezas en el tablero, cuáles son las reglas que
definen los movimientos legales y qué posiciones de las piezas representan la victoria
tanto para un jugador como para el otro.
La posición inicial y en general cualquier posición, puede describirse con una tabla de
8x8 elementos.
La meta es una posición del tablero en la cual el jugador contrario tenga su rey
amenazado y no pueda realizar ningún movimiento legal para quitarse la amenaza.
Los movimientos legales son la forma de pasar, desde un estado inicial a un estado meta
y pueden describirse como un conjunto de reglas del tipo "si X entonces Y" donde 'X' y
'Y' son posiciones legales del tablero y significa que se puede 'pasar' del estado 'X' al
estado 'Y' :

a b c d E f g h A b c d e f g h
8 TN CN AN RN DN AN CN TN 8 TN CN AN RN DN AN CN TN
7 PN PN PN PN PN PN PN PN 7 PN PN PN PN PN PN PN PN
6 6
5 5
4 4 PB
3 3
2 PB PB PB PB PB PB PB PB 2 PB PB PB PB PB PB PB
1 TB CB AB RB DB AB CB TB 1 TB CB AB RB DB AB CB TB

Estado X Estado Y

Figura 2.5. Tablero de Ajedrez

Acabamos de definir el problema de jugar ajedrez como un problema de movimientos a


través de un espacio de estados; la resolución de problemas con búsqueda en un espacio
de estados forma la base de muchas aplicaciones de inteligencia artificial.

FACULTAD DE MATEMATICAS
Fundamentos de Inteligencia Artificial 5

2.2. Sistemas de Producción.


Un sistema de producción es una técnica computacional cuyo efecto es convertir a la
computadora en una máquina más ó menos experta en la resolución de problemas
específicos, es decir, restringidos a un cierto dominio de conocimientos.
El concepto en que se basan los sistemas de producción es una extensión de la idea de las
estructuras iterativas de la programación tradicional: un sistema de producción itera
continuamente hasta que se satisfagan una ó varias condiciones que implican
normalmente la solución ó la imposibilidad de resolver los problemas planteados.

Un sistema de producción consiste de :

-Un conjunto de reglas del tipo "si X entonces Y".


-Una base de conocimientos que contenga información útil para la tarea a realizar.
-Una estrategia de control que especifique el orden en que se aplicarán las reglas y que
resuelva los conflictos que se puedan presentar.
-Un aplicador de reglas.

el algoritmo básico del aplicador de reglas puede escribirse en forma no determinística


como sigue :

algoritmo sisprod.
1. [Establecer la base de datos inicial.]
DATOS <--- base de datos inicial;
2. [Aplicar reglas hasta que se satisfaga alguna condición de terminación
del problema (éxito ó fracaso)]
while DATOS no satisfaga la condición de terminación del problema
{
seleccionar alguna regla R del conjunto de reglas, tal que
pueda ser aplicada a DATOS;
DATOS <--- resultado de aplicar R a DATOS;
}
3. [Fin]
presentar los resultados.
end.

éste algoritmo es no determinístico porque todavía no hemos especificado la estrategia de


control (seleccionar), es decir, cómo se va a seleccionar en cada iteración la regla que se
aplicará (puede haber más de una regla aplicable); de éste modo, la operación de un
sistema de producción puede caracterizarse como un proceso de búsqueda en el cual, las
reglas se van probando hasta que se encuentra alguna secuencia de ellas que satisfagan
alguna condición de terminación. En realidad, las estrategias de control, para ser
eficientes, requieren conocer el tipo de problema que se va a resolver.

FACULTAD DE MATEMATICAS
Fundamentos de Inteligencia Artificial 6

2.3. Heurísticas

Para solucionar la mayoría de los problemas difíciles, a menudo es necesario construir


una estructura de control que aunque no nos garantice encontrar la mejor respuesta, por
lo menos proporcione una respuesta satisfactoria para nuestros propósitos. Una técnica
heurística es aquélla que mejora la eficiencia del proceso de búsqueda de soluciones a
cambio, posiblemente, de sacrificar su completitud. Como ejemplo de aplicación de
técnicas heurísticas consideraremos un problema clásico de optimización :

El problema del agente viajero.

Un vendedor tiene una lista de ciudades cada una de las cuales debe visitar solamente una
vez; existen carreteras directas entre cada par de ciudades de la lista. Se debe encontrar la
ruta que el vendedor debería seguir para que, siguiendo el camino más corto posible,
visitara todas las ciudades, comenzando por cualquiera de ellas y volviendo a la misma.
Un ejemplo de éste tipo de problemas para seis ciudades se plantea en la figura 2.6.

1 2 3 4 5 6
1 2
1 13 12 18 7 14
2 13 21 26 15 25
3 12 21 11 6 4
6 3
4 18 26 11 12 14
5 7 15 6 12 9
5 4 6 14 25 4 14 9

Red de Ciudades Matriz de distancias

Figura 2.6. El problema del agente viajero.

En principio se puede resolver éste problema explorando el árbol de todos los caminos
posibles y eligiendo aquél que tenga la longitud mínima; pero, si existen n ciudades, el
número de caminos diferentes entre ellas es (n-1)!, esto significa que el tiempo requerido
para resolver el problema es proporcional a n!. Por lo tanto, si tenemos once ciudades,
(11-1)! = 10*9*8*7*6*5*4*3*2*1 = 3,628,000 rutas son posibles, es decir, se trata de un
problema típico de explosión combinatoria en el que es útil aplicar técnicas heurísticas.

Una técnica heurística de propósito general que es útil para resolver problemas
combinatorios es el 'algoritmo del vecino más próximo', que trabaja seleccionando la
alternativa más cercana que aún no ha sido visitada y así sucesivamente hasta recorrer
todos los nodos y retornar al punto de partida :

1. Seleccionar arbitrariamente una ciudad de partida.

FACULTAD DE MATEMATICAS
Fundamentos de Inteligencia Artificial 7

2. Para seleccionar la siguiente ciudad, analizar todas las ciudades que aún no se han
visitado y seleccionar aquélla que sea la más cercana a la ciudad actual; ir a ella en el
siguiente paso.
3. Repetir el paso dos hasta que se hayan visitado todas las ciudades.

éste algoritmo se ejecuta en un tiempo proporcional al cuadrado de n lo que representa


una mejora significativa sobre n!.

Ejercicio. Implemente el algoritmo del vecino más próximo en lenguaje Lisp ó prolog y
resuelva el problema planteado en la figura 2.6.

Ejercicio. Utilice el algoritmo anterior para resolver el siguiente problema: imagine que
usted es un agente de viajes y que un cliente le pide que le reserve su pasaje en algún
vuelo de Nueva York a Los Angeles, pero con la aerolínea XYZ ya que el cliente tiene un
pase de cortesía; usted observa la lista de vuelos de XYZ y encuentra que no existe un
vuelo directo y que tendrá que hacer la reservación utilizando transbordos.

Calgary 1500 millas


Toronto
800
500
1800 1000 Nueva York
Chicago
1000
1900
Denver
Los Angeles Urbana
1000
1000
1500
1500

Houston

FACULTAD DE MATEMATICAS
Fundamentos de Inteligencia Artificial 8

3. Métodos para la solución de problemas.

En éste capítulo se presentan los métodos más importantes de propósito general para la
búsqueda de soluciones a los problemas presentados en el capítulo anterior; para la
búsqueda de éstas soluciones se han desarrollado técnicas como las siguientes :

-Búsqueda ciega.
-Primero en profundidad.
-Primero a lo ancho.
-Solución por costo mínimo.
-Reducción de Problemas, grafos AND/OR,
árboles de juegos.
-Heurística, funciones de evaluación, búsquedas heurísticas en
grafos AND/OR.
-Técnicas de poda : alfa, beta, alfa-beta, hacia adelante y otras.

3.1. Métodos Básicos.

Primero en profundidad.
Explora cada camino posible hasta su conclusión antes de intentar otro camino.
Ejemplo :

B C

D E F G

Figura 3.1. Búsqueda en profundidad

FACULTAD DE MATEMATICAS
Fundamentos de Inteligencia Artificial 9

Primero a lo ancho.
Explora cada nodo sobre el mismo nivel antes de intentar analizar un nivel más profundo.
Ejemplo :

B C

D E F G

Figura 3.2. Búsqueda a lo ancho

Ascenso de la colina.
Escoge como próximo paso el nodo que aparezca en el lugar más cercano a la meta; éste
método se basa en la analogía de un excursionista perdido en la oscuridad en la mitad de
una montaña donde él sabe que cualquier paso hacia arriba lo sitúa en la dirección
correcta.
Un algoritmo posible para éste método es el siguiente :

1. Generar la primera solución propuesta de la misma forma que se haría en el algoritmo


para el método de generar-y-comprobar; ver si es una solución; si lo es, terminar; de lo
contrario continuar.
2. Una vez obtenida dicha solución, aplicar algunas reglas para generar un conjunto
nuevo de soluciones propuestas.
3. Para cada elemento del conjunto hacer lo siguiente :
a). Enviarlo a la función de comprobación; si es la solución,
terminar.
b). Si no lo es, ver si está más cerca de la solución que cualquiera de
los elementos comprobados hasta el momento; si lo es, recordarla;
si no lo es, olvidarla.
4. Tomar el mejor elemento encontrado anteriormente y usarlo como la siguiente
solución propuesta; éste paso corresponde a un movimiento a través del espacio del
problema en la dirección que parece conducir más rápidamente hacia la meta.
5. Regresar al paso número dos.

FACULTAD DE MATEMATICAS
Fundamentos de Inteligencia Artificial 10

Ejemplo 1. El problema del laberinto.


En las figuras 3.3 y 3.4 se muestra un ejemplo del problema a resolver (salida de un
laberinto) y la gráfica de su espacio de estados.

2 3 4
6 7 8
9 10 11
5
1 21
13 14 12
15
17 18 16
19 20

Figura 3.3. Salida de un laberinto.

3 4
2

8
5 6 7

10 11 21
14 9

1 15 16
13 12

17 18

19 20

Figura 3.4. Espacio de estados del problema.

FACULTAD DE MATEMATICAS
Fundamentos de Inteligencia Artificial 11

la búsqueda en profundidad pasa de cada nodo a su primer sucesor no revisado: si éste es


la meta ya se encontró el camino que buscamos; si no lo es, se pasa a su primer sucesor y
así se continúa. Si el nodo ya no tiene sucesores no revisados, se pasa al siguiente sucesor
no revisado de su predecesor y se aplica la misma estrategia. El orden en que se visitan
los nodos depende naturalmente de la manera en que se toman en cuenta los sucesores, si
éstos están ordenados entre sí (usando por ejemplo alguna numeración global), el orden
de búsqueda es único.
Saliendo del nodo 1 y tomando los sucesores en orden creciente, de acuerdo con sus
números, para la gráfica de la figura 3.3 recorrida en profundidad, encontramos la
siguiente secuencia de nodos :

1, 9, 6, 2, 3, 4, 21

a). Solución en Lisp.

Ahora nuestro objetivo es programar el método en Lisp: supongamos que nuestra tarea es
encontrar un camino de un nodo A a un nodo Z en una gráfica G. Después de realizar
algunos pasos de la búsqueda en profundidad nos vamos a encontrar en una situación
general esquematizada en la figura 3.5.

A ... X Y ... Z

P1

Figura 3.5. Búsqueda en profundidad.

llegamos hasta el nodo X usando algún camino parcial P1 y hay que decidir cómo
continuar. Si el nodo X coincide con Z, se terminó la búsqueda y el camino P1 es el
resultado. Si todavía no llegamos a la meta y X no tiene ningún sucesor hay que regresar
a su predecesor y continuar usando el próximo hermano de X disponible. Si X todavía
tiene sucesores disponibles, se toma el primero de ellos (sea éste Y), el camino parcial P1
se prolonga hasta él y el proceso se repite.

Diseñamos una función recursiva path1 con argumentos X, Z, P1, G, SCX, cuya tarea es
realizar los pasos especificados arriba; SCX representa la lista de los sucesores
disponibles del nodo X (son los sucesores que todavía no se encuentran en el camino
parcial P1). La definición de la función path1 se muestra a continuación :

FACULTAD DE MATEMATICAS
Fundamentos de Inteligencia Artificial 12

(defun path1 (x z p1 g scx)


(prog (p)
(return (cond
; se terminó la búsqueda
((eq x z) p1)
; no hay sucesores
((null scx) nil)
; se toma el primer sucesor disponible y se prueba
((setq p (path1 (car scx)
z
(cons (car scx) p1)
g
(sucd (car scx) g p1)
) ) p)
; el primer sucesor no tuvo éxito, se quita de la lista
; de sucesores y se repite la búsqueda
(t (path1 x z p1 g (cdr scx))) )
)))

en ésta función, primero se prueba si los nodos X y Z coinciden, y en éste caso se regresa
P1 como resultado. Luego se averigua si hay todavía sucesores disponibles y se reporta
falla (nil) en caso contrario (el regreso al predecesor de X y el uso de los hermanos de X
está asegurado por la recursión y las alternativas que siguen).

Luego se toma el primer sucesor disponible y se busca algún camino entre él y el nodo Z
llamando otra vez la misma función path1 con argumentos ajustados apropiadamente (la
función SUCD determina los sucesores disponibles y por ésto necesita tener acceso al
camino parcial P1). Si el avance por el primer sucesor no tuvo éxito, éste se quita de la
lista SCX y se repite la búsqueda con la lista reducida.

La función que llama a path1 y que representa el algoritmo completo de búsqueda en


profundidad es el siguiente :

(defun pathdep (a z g)
(reverse
(path1 a z (list a) g (sucd a g (list a))) ))

ésta función llama a la función path1 dándole el nodo inicial (n1), el nodo meta (n21), el
camino parcial (contiene inicialmente sólo a n1), la gráfica g, y los sucesores disponibles
que se determinan usando la función sucd.

La gráfica dirigida G se puede representar en Lisp utilizando una lista de la siguiente


forma :

(setq g '( (n1 n9 n12) (n2 n3 n5 n6 n7) (n3 n2 n4 n8) (n4 n3 n8 n21)

FACULTAD DE MATEMATICAS
Fundamentos de Inteligencia Artificial 13

(n5 n2 n6) (n6 n2 n5 n9) (n7 n2 n9) (n8 n3 n4 n10)


(n9 n1 n6 n7 n12) (n10 n8 n11 n15) (n11 n10)
(n12 n1 n9 n14 n17) (n13 n14 n17 n19) (n14 n12 n13)
(n15 n10 n16 n18) (n16 n15 n20) (n17 n12 n13 n19)
(n18 n15) (n19 n13 n17 n20) (n20 n16 n19) (n21 n4) ))

en que para cada nodo se mencionan explícitamente todos sus nodos sucesores.

La función sucd elige al primer sucesor disponible apoyándose en la función auxiliar dif :

(defun sucd (n g p1)


(cond ((null g) nil)
((eq (caar g) n) (dif (cdar g) p1))
(t (sucd n (cdr g) p1)) ))

(defun dif (p q)
(cond ((null p) nil)
((member (car p) q) (dif (cdr p) q))
(t (cons (car p) (dif (cdr p) q))) ))

en la función sucd, si el nodo es N, la lista de todos sus sucesores (cdar G) se pasa a la


función dif; si el primer nodo no es N, se llama recursivamente la misma función sucd
dándole ésta vez la gráfica G sin el primer nodo y así en adelante. Si el nodo no se
encontró, sucd regresa la lista vacía NIL.

Cabe recordar que la función (caar G) es una abreviación de (car (car G)) y se usa como
selector del primer nodo de la gráfica G; asimismo (cdar G) es abreviación de (cdr (car
G)); ésto se ilustra en la figura 3.6 siguiente :

(CAR G) (CDR G)

G = ( ( n1 s11 s12 . . . ) ( n2 . . . ) ... )

(CAAR G) (CDAR G)

Figura 3.6. Representación de la Gráfica G.

el algoritmo completo de búsqueda en profundidad es el siguiente :

FACULTAD DE MATEMATICAS
Fundamentos de Inteligencia Artificial 14

;-------------------------------------------------------------------------------------
; busprof1.lsp

;----------------------------------------------------------------------------------
; Representación de la gráfica g.
(setq g '( (n1 n9 n12) (n2 n3 n5 n6 n7) (n3 n2 n4 n8) (n4 n3 n8 n21)
(n5 n2 n6) (n6 n2 n5 n9) (n7 n2 n9) (n8 n3 n4 n10)
(n9 n1 n6 n7 n12) (n10 n8 n11 n15) (n11 n10)
(n12 n1 n9 n14 n17) (n13 n14 n17 n19) (n14 n12 n13)
(n15 n10 n16 n18) (n16 n15 n20) (n17 n12 n13 n19)
(n18 n15) (n19 n13 n17 n20) (n20 n18 n19) (n21 n4) ))

;--------------------------------------------------------
(defun pathdep (a z g)
(reverse
(path1 a z (list a) g (sucd a g (list a))) ))

;--------------------------------------------------------
(defun path1 (x z p1 g scx)
(prog (p)
(return (cond
((eq x z) p1)
((null scx) nil)
((setq p (path1 (car scx)
z
(cons (car scx) p1)
g
(sucd (car scx) g p1)
) ) p)
(t (path1 x z p1 g (cdr scx))) )
)))

;----------------------------------------------------------------
(defun sucd (n g p1)
(cond ((null g) nil)
((eq (caar g) n) (dif (cdar g) p1))
(t (sucd n (cdr g) p1)) ))

(defun dif (p q)
(cond ((null p) nil)
((member (car p) q) (dif (cdr p) q))
(t (cons (car p) (dif (cdr p) q))) ))

FACULTAD DE MATEMATICAS
Fundamentos de Inteligencia Artificial 15

Ejemplo de ejecución :

A:\> mulisp common <enter>


;Loading A:COMMON.LSP

$(load busprof1) <enter>


;Loading A:BUSPROF1.LSP
T

$(pathdep 'n1 'n21 g) <enter>


(N1 N9 N6 N2 N3 N4 N21)

$(pathdep 'n1 'n1 g) <enter>


(N1)

$(pathdep 'n18 'n21 g) <enter>


(N18 N15 N10 N8 N3 N4 N21

$(pathdep 'n4 'n21 g) <enter>


(N4 N21)

$(system) <enter>

A:\> _

FACULTAD DE MATEMATICAS
Fundamentos de Inteligencia Artificial 16

b). Solución en Prolog.


La relación path1 tendrá los mismos cuatro primeros argumentos de la función path1 de
Lisp más un argumento que se utilizará para el resultado (el camino final). En las
relaciones de Prolog que corresponden a las funciones de Lisp siempre hay que reservar
un argumento aparte para el resultado. La definición de path1 la componen las cláusulas :

; el camino trivial: estamos en la meta.


path1( Z, Z, P, _, P ).
; El caso general: se elige algún sucesor disponible y
; se sigue adelante.
path1( X, Z, P1, G, P ) :-
sucd( X, G, P1, Y) ,
path1( Y, Z, [Y | P1], G, P).

la coincidencia del primer y segundo argumento distingue el caso trivial y se expresa


usando la misma variable en ambos lados: dado que los dos primeros argumentos de
path1 siempre tendrán algún valor asociado, el proceso de empatamiento simplemente
averigua la igualdad de sus valores. La misma variable P en el tercer y quinto argumento
significa otra cosa: ésta vez se expresa así la asignación del resultado al último
argumento sabiendo que la realizará Prolog en el proceso de empatamiento (matching).
La segunda cláusula expresa la regla general: se toma el primer sucesor disponible Y y se
avanza adelante prolongando el camino parcial P1 por Y.
La relación pathdep se puede definir por la cláusula :

pathdep(A, Z, G, P) :-
path1(A, Z, [A], G, Pr) ,
invertir(Pr, P).

en el cuerpo de ésta cláusula se usa primero la relación path1 dándole los nodos límites
(A y Z) y el camino parcial que corresponde al inicio del algoritmo (la lista con un sólo
elemento: A); luego se invierte el resultado de path1 recibiendo así el camino final
buscado P.

La relación sucd se supone que determina al primer sucesor disponible (ó bien falla); para
su implantación usaremos la misma representación de la gráfica G como lo hicimos en
Lisp siendo la única diferencia la forma en que Prolog expresa y accesa las listas. La
definición de sucd la componen las cláusulas :

% Se encontró el nodo X: elige el próximo


% sucesor que no está en P1.
sucd(X, [ [ X | Scx ] | _ ], P1, Y) :-
!, miembro(Y, Scx),
not miembro(Y, P1).
% Se investiga el resto de la gráfica.
sucd(X, [ _ | GRest], P1, Y) :-
sucd(X, GRest, P1, Y).

FACULTAD DE MATEMATICAS
Fundamentos de Inteligencia Artificial 17

la primera regla corresponde al caso en que ya se encontró el nodo X y sus sucesores en


la representación de la gráfica G: el proceso de empatamiento asegura las asociaciones
que se ven en la figura 13. Usando la relación member se elige algún elemento Y de la
lista de sucesores Scx (que adquirió su valor en el empatamiento con la cabeza) y se
verifica si no está en el camino parcial P1. Si está allí, el retroceso automático de Prolog
llama otra vez la relación member para que le dé el siguiente elemento de la lista Scx y
así se procede hasta que se encuentre algún sucesor disponible ó bien la relación sucd
falle.
G = [ [ n1 s11 s12 . . . ] [ n2 . . . ] . . . ]

[[ X | ScX ] | _ ]

Figura 3.7. Representación de la Gráfica G.

La segunda regla sirve solamente para recorrer la gráfica G en la búsqueda de la parte


que informa sobre los sucesores del nodo X y se toma en consideración sólo si la primera
regla no se pudo usar (ó sea que su cabeza no empató), ésto asegura el corte.

Por último es importante destacar el caracter diferente de los dos usos de member en la
primera regla: en el primer caso tiene definido solamente su segundo argumento (la lista)
y entonces con cada paso de retroceso asocia con el primer argumento el próximo
elemento de la lista. En el segundo caso se trata del uso convencional de member.
El algoritmo completo de búsqueda en profundidad es :

%---------------------------------------------
% busprof1.ari
%--------------------------------------------
pathdep(A, Z, G, P) :-
path1(A, Z, [A], G, Pr),
invertir(Pr, P).
path1(Z, Z, P, _, P).
path1(X, Z, P1, G, P) :-
sucd(X, G, P1, Y),
path1(Y, Z, [Y | P1], G, P).
sucd(X, [[X | Scx] | _ ], P1, Y) :-
!, miembro(Y, Scx),
not miembro(Y, P1).
sucd(X, [_ | GRest], P1, Y) :- sucd(X, GRest, P1, Y).
invertir([],[]).
invertir([Cabeza | Cola], Linvertida) :-
invertir(Cola, Colainvertida),
concatenar(Colainvertida, [Cabeza], Linvertida).
concatenar([],L,L).
concatenar([X | L1], L2, [X | L3]) :- concatenar(L1, L2, L3).

FACULTAD DE MATEMATICAS
Fundamentos de Inteligencia Artificial 18

miembro(X, [ X | _ ]).
miembro(X, [ _ | Cola ]) :- miembro(X, Cola).
resolver(Ni, Nf, P) :- pathdep( Ni, Nf,
[[n1, n9, n12],[n2,n3,n5,n6,n7], [n3,n2,n4,n8], [n4,n3,n8,n21],
[n5,n2,n6], [n6,n2,n5,n9],[n7,n2,n9], [n8,n3,n4,n10],
[n9,n1,n6,n7,n12], [n10,n8,n11,n15], [n11,n10],
[n12,n1,n9,n14,n17], [n13,n14,n17,n19], [n14,n12,n13],
[n15,n10,n16,n18], [n16,n15,n20], [n17,n12,n13,n19],
[n18,n15], [n19,n13,n17,n20], [n20,n16,n19],[n21,n4]], P).

Ejemplo de ejecución :

A:\> api <enter>


?- consult( 'busprof1.ari' ). <enter>
yes
?- resolver( n1, n21, X ). <enter>

X = [n1,n9,n6,n2,n3,n4,n21] -> ;
X = [n1,n9,n6,n2,n3,n8,n4,n21] -> ;
X = [n1,n9,n6,n5,n2,n3,n4,n21] -> ;
X = [n1,n9,n6,n5,n2,n3,n8,n4,n21] -> ;
X = [n1,n9,n7,n2,n3,n4,n21] -> ;
X = [n1,n9,n7,n2,n3,n8,n4,n21] -> ;
X = [n1,n9,n12,n14,n13,n17,n19,n20,n16,n15,
n10,n8,n4,n21] -> <enter>
yes
?- halt. <enter>

A:\> _

c). Comparación de las soluciones.


La diferencia más importante entre los programas en Lisp y Prolog reside en la forma en
que se asegura el uso consecutivo de todos los sucesores disponibles de cada nodo: en
Lisp se logró incluyendo un argumento más (ó sea en forma explícita), en Prolog se
aprovechó el mecanismo de retroceso automático (backtracking) (ó sea la forma
implícita). Otra diferencia es la simplicidad de la definición de sucd en prolog ya que no
necesitó las dos etapas de Lisp (sucd y dif); aprovechando el proceso de empatamiento
con la cabeza de la primera regla, en el cuerpo de sucd queda sólo implementar la
operación que realizaba la función dif.

FACULTAD DE MATEMATICAS

Das könnte Ihnen auch gefallen