You are on page 1of 17

ESCUELA POLITCNICA NACIONAL

FACULTAD DE INGENIERA DE SISTEMAS

INGENIERA EN SISTEMAS INFORMTICOS Y


COMPUTACIN

INTELIGENCIA ARTIFICIAL

ALMENDRIZ VANESSA
MOLINA SAMANTHA

IMPLEMENTACIN DE LA TCNICA DE BSQUEDA

01 DE DICIEMBRE DEL 2014

NDICE
pg.
Contenidos
NDICE ................................................................................................................................................2
Tabla de Figuras .........................................................................................................................2
Introduccin ...................................................................................................................................3
Marco Terico ................................................................................................................................3
Bsqueda no informada .............................................................................................................3
Problema ....................................................................................................................................4
Implementacin Conceptual ..........................................................................................................4
Diagrama de estados completos ................................................................................................5
Implementacin Computacional ....................................................................................................5
Resultados ......................................................................................................................................8
Conclusiones ..................................................................................................................................9
Anexos ..........................................................................................................................................10

Tabla de Figuras
Figura 1: Generar estados. .................................................................................................................6
Figura 2: Mtodo clone implementado para las funciones regresar y enviar. ...................................6
Figura 3: Comprobacin del nmero de canbales y de misioneros. ..................................................6
Figura 4: Funcin sucesor. ..................................................................................................................7
Figura 5: Funcin Arbol en la Clase Arbol ...........................................................................................7
Figura 6: rbol que contiene los estados alcanzables por el agente. .................................................8
Figura 7: Resultado de la bsqueda primero en profundidad con profundidad iterativa...................9

Introduccin
Uno de los problemas que se analiza en Inteligencia Artificial es el problema de los
canbales y los misioneros, en el cual se parte de un estadio inicial con tres
canbales y tres misioneros en una orilla y el estado objetivo es llevar a los seis a
la otra orilla. Para hallar la solucin de este problema se ha usado la bsqueda
primero en profundidad con profundidad iterativa, que es una estrategia de la
bsqueda no informada, con la eliminacin de estados repetidos.

Marco Terico
Bsqueda no informada

La bsqueda no informada, tambin conocida como bsqueda a ciegas, es un tipo


de bsqueda que consiste en partir de un estado inicial para generar todos los
estados posibles mediante los cuales se pueda encontrar la solucin, cada vez
que genera un estado lo compara con el estado objetivo. Si el estado actual es el
estado objetivo encuentra solucin, caso contrario genera un nuevo estado [1].
La bsqueda no informada posee cinco estrategias, estas son [1]:
a) Bsqueda en anchura
b) Bsqueda de costo uniforme
c) Bsqueda primero en profundidad
d) Bsqueda de profundidad limitada
e) Bsqueda primero en profundidad, con profundidad iterativa.
Bsqueda primero en profundidad con profundidad iterativa

La bsqueda primero en profundidad con profundidad iterativa, tambin conocida


como bsqueda con profundidad iterativa, es una de las mejores estrategias que
ofrece la bsqueda no informada. Esto debido a que combina las ventajas que
ofrecen la bsqueda por anchura y bsqueda primero en profundidad [1].
Consiste en ir aumentando gradualmente el lmite del rbol, comienza desde el
nivel 0 y en cada iteracin aumenta un nivel, en cada uno de estos se genera el
rbol nuevamente. Esta estrategia es usada, especialmente, cuando el espacio de
bsqueda es grande y no se conoce la profundidad de la solucin [1].
Estados repetidos

Uno de los problemas que enfrenta este tipo de bsqueda es la generacin de


estados repetidos, para que este inconveniente se resuelve es conveniente llevar
un registro de los estados visitados y comparar con el estado a generar para
agregarlo, en el caso de que no est presente en la lista, o para excluirlo, en el
caso de que se encuentre dentro de la lista.

Problema

El problema de los tres misioneros y los tres canbales radica en un estado inicial,
donde los seis se encuentran en un lado de la orilla, y un estado objetivo que
consiste en llevar a los seis al otro lado de la orilla. Para el transporte se tiene una
canoa, en la cual pueden viajar dos personas (puede ser un misionero y un
canbal, o dos canbales o dos misioneros) o una (un misionero o un canbal).
Tambin se debe considerar las restricciones, en estas se establece
que el
nmero de canbales no puede superar al nmero de misioneros debido a que los
canbales devorarn al misionero y ya no se podra llegar al estado objetivo.

Implementacin Conceptual
El objetivo del problema es pasar a todos a la otra orilla. La condicin que se pone
es que slo se puede pasar a dos personas a la vez y que no debe ocurrir nunca
que en una de las orillas haya un nmero mayor de canbales que de misioneros,
ya que se los comeran.
Estado inicial:
I
M:3;C:3

D
M:0;C:0

Estado objetivo:
I
M:0;C:0

D
M:3;C:3

Condicin: No debe existir #canbales > #misioneros en cualquier orilla.


Estados:
Parmetros:
Nmero de misioneros a la izquierda, nmero de canbales a la izquierda,
nmero de misioneros a la derecha, nmero de canbales a la derecha,
posicin bote.
Operaciones:
Transportar 2 misioneros.
Transportar 2 canbales.
Transportar 1 misionero y 1 canbal.

Diagrama de estados completos


M:3;C:3

M:0;C:0

M:2;C:2

M:1;C:1

M:3;C:1

M:0;C:2

M:2;C:2

M:1;C:1

M:3;C:2

M:0;C:1

M:3;C:0

M:0;C:3

M:3;C:1

M:0;C:2

M:2;C:1

M:0;C:3

M:3;C:0

M:0;C:1

M:3;C:2

M:1;C:2

M:1;C:1

M:2;C:2

M:2;C:2

M:1;C:1

M:2;C:2

M:1;C:1

M:2;C:2

M:1;C:1

M:0;C:2

M:3;C:1

M:3;C:1

M:1;C:1

M:2;C:2

M:0;C:0

M:3;C:3

M:0;C:0

M:3;C:3

M:1;C:2

M:2;C:0

M:1;C:2

M:0;C:2

M:1;C:3

M:2;C:0

M:2;C:1

M:1;C:3

M:2;C:1

Implementacin Computacional
Para resolver el problema de manera ptima se ha utilizado un algoritmo con
bsqueda en profundidad en el lenguaje de programacin JAVA en Eclipse Luna.
Se cre una clase estado, donde se defini el nmero de misioneros a la
izquierda, nmero de canbales a la izquierda, nmero de misioneros a la derecha,
nmero de canbales a la derecha y posicin bote (1: derecha, 0: izquierda. ). Los
estados se implementan en una lista.

Para la generacin de estados se crea dos funciones: enviar y regresar.

Figura 1: Generar estados.

En estas dos funciones se implementa un clonable para poder clonar los estados.
El mtodo clone copia y regresa un cln del objeto. [2]

Figura 2: Mtodo clone implementado para las funciones regresar y enviar.

Despus se comprueba que los canbales no sean mayores a los misioneros en


cada orilla, para evitar un error (que se coman los misioneros).

Figura 3: Comprobacin del nmero de canbales y de misioneros.

Se crea una funcin sucesor que es una funcin recursiva. Ayuda a comprobar si
el estado est en la lista y si ha aparecido para evitar que se repitan los estados
que ya han pasado. Se establece el estado objetivo al que tiene que llegar (0, 0, 3,
3, 0 ).
Si, no cumple con las condiciones, salta al siguiente elemento de la lista de nodos
hijos, el else if es igual al estado objetivo. Para la ejecucin, el else es la parte
recursiva que manda a generar estados de ese nodo, verifica si esta a la izquierda
o a la derecha y en funcin de eso, enva o regresa. Puede enviar o regresar 2
canbales, 2 misioneros o 1 canbal y 1 misionero.

Figura 4: Funcin sucesor.

Mientras va buscando el estado objetivo, existe un caso especial en el que regresa


1 misionero o 1 canbal, sino nunca pasa y se repite mientras no llegue a la
solucin.
Para generar el rbol de forma grfica, se cre una clase Arbol y se us los
mtodos para hacer rboles de JAVA.

Figura 5: Funcin Arbol en la Clase Arbol

Resultados
Para realizar la bsqueda no informada, con la estrategia primero en profundidad
con profundidad iterativa, es necesario generar un rbol de los estados
alcanzables por el agente; en este rbol se han eliminado los estados repetidos,
esto debido a que ayuda a optimizar los la bsqueda.
En la Figura 6 se muestra el rbol generado, en el cual se muestra los posibles
caminos que puede seguir el agente para cumplir el objetivo. Tanto los estados
repetidos como los estados que no permiten cumplir con el objetivo son nodos
hoja.
Una vez generados los estados posibles, se procede a realizar la bsqueda, el
resultado de esta se muestra en la Figura 7. La bsqueda se realiza por niveles
hasta encontrar llegar al objetivo, PASA DE NODO cuando ha llegado a un
estado que no le permite cumplir con el objetivo y ENCUENTRA EL OBJETIVO,
cuando ha llegado al estado deseado.

Figura 6: rbol que contiene los estados alcanzables por el agente.

Figura 7: Resultado de la bsqueda primero en profundidad con profundidad iterativa.

La eliminacin de estados repetidos del rbol permite obtener una solucin ptima
mediante la disminucin de la utilizacin de recursos, tales como memoria y
tiempo. Los estados repetidos pueden demorar el hallazgo de la solucin cuando
esta no se encuentre en el inicio del rbol. Esto se debe a que tiene que recorrer
todo el rbol inclusive con estados ya visitados, la eliminacin de estos disminuye
el tiempo en el cual se realizar la misma, al igual que el uso de la memoria ya
que slo almacena los estados no repetidos.
A pesar de ser un problema simple el agente afronta ciertos problemas durante
la resolucin del mismo, esto se debe a que existe una cantidad considerable de
estados posibles y l debe ir evaluando cada uno de ellos considerando las
restricciones del problema.

Conclusiones

En este tipo de problemas de bsqueda no informada es de importancia para el


agente tener una meta especfica, y determinar las posibles estrategias u
acciones.
Si se establece condiciones o informacin sobre los estados sucesores, es
posible que no afecte de forma importante el nmero de movimientos para
llegar al estado objetivo. Sin embargo, cuando se analiza cada movimiento
pueden existir nodos que provoquen un bucle infinito y por lo tanto es
necesario reducir o quitar esos estados.
Una manera eficiente para resolver este problema es que no tenga ciclos y
estados repetidos. Estos deben ser eliminados. El nivel al que llega el rbol
para su solucin es el nivel 11.

Referencias
[1] M. Rouse, SearchSecurity, Julio 2006. [En lnea]. Available:
http://searchsecurity.techtarget.com/definition/Transport-Layer-Security-TLS. [ltimo acceso:
13 octubre 2014].
[2] Tutorialspoint, Java - Methods, 2009. [En lnea]. Available:
http://www.tutorialspoint.com/java/lang/object_clone.htm. [ltimo acceso: 30 noviembre
2014].

Anexos
CLASE ARBOL
package artificial;
import java.awt.*;
import java.util.ArrayList;
import
import
import
import

javax.swing.*;
javax.swing.event.TreeSelectionListener;
javax.swing.event.TreeSelectionEvent;
javax.swing.tree.*;

public class Arbol extends JFrame {


private JTree tree;
public static void main(String[] args) {
Arbol a = new Arbol();
}
public Arbol() {
Estado estadoInicial = new Estado(3, 3, 1);
estadoInicial.generarEstados();
java.util.List<Estado> estadosObtenidos = new ArrayList<>();
estadosObtenidos.add(estadoInicial);
DefaultMutableTreeNode raiz = new
DefaultMutableTreeNode(estadoInicial);
funcionSucesor(estadoInicial, estadosObtenidos, raiz);
Container content = getContentPane();
tree = new JTree(raiz);
ToolTipManager.sharedInstance().registerComponent(tree);
content.add(new JScrollPane(tree), BorderLayout.CENTER);
setSize(900, 900);

setVisible(true);
}
public static void funcionSucesor(Estado estadoActual,
java.util.List<Estado> estadosObtenidos, DefaultMutableTreeNode padre) {
Estado objetivo = new Estado(0, 0, 3, 3, 0);
for (Estado e : estadoActual.getEstados()) {
if (!estadosObtenidos.contains(e)) {
if ((e.getNumeroCanibalesDerecha() >
e.getNumeroMisionerosDerecha() && e.getNumeroMisionerosDerecha() != 0) ||
(e.getNumeroCanibalesIzquierda() > e.getNumeroMisionerosIzquierda() &&
e.getNumeroMisionerosIzquierda() != 0)) {
estadosObtenidos.add(e);
DefaultMutableTreeNode nodo = new
DefaultMutableTreeNode(e);
padre.add(nodo);
System.out.println("PASA DE NODO: " + e.toString());
//continue;
} else if (e.equals(objetivo)) {
DefaultMutableTreeNode nodo = new
DefaultMutableTreeNode(e);
padre.add(nodo);
System.out.println("ENCONTRO EL OBJETIVO");
break;
} else {
estadosObtenidos.add(e);
System.out.println(e.toString());
DefaultMutableTreeNode nodo = new
DefaultMutableTreeNode(e);
padre.add(nodo);
e.generarEstados();
funcionSucesor(e, estadosObtenidos, nodo);
}
}
}
}
private class MyTreeRenderer extends DefaultTreeCellRenderer {
public Component getTreeCellRendererComponent(JTree tree, Object
value, boolean sel, boolean expanded, boolean leaf, int row, boolean
hasFocus) {
JComponent component = (JComponent)
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row,
hasFocus);
Object selected = ((DefaultMutableTreeNode)
value).getUserObject();
if (selected instanceof MyTreeClass) {
component.setToolTipText(((MyTreeClass)
selected).getToolTip());
}
return component;
}
}
private class MyTreeClass {

private Estado estado;


public MyTreeClass(Estado estado) {
this.estado = estado;
}
public Estado getEstado() {
return estado;
}
public void setEstado(Estado estado) {
this.estado = estado;
}
public String getToolTip() {
return "hijo";
}
}
}

CLASE ESTADO
package artificial;
import
import
import
import

java.util.ArrayList;
java.util.List;
java.util.logging.Level;
java.util.logging.Logger;

public class Estado implements Cloneable {


/**
* Numero de misioneros en el lado izquierdo.
*/
private int numeroMisionerosIzquierda;
/**
* Numero de canibales en el lado izquierdo.
*/
private int numeroCanibalesIzquierda;
/**
* Numero de misioneros en el lado izquierdo.
*/
private int numeroMisionerosDerecha;
/**
* Numero de canibales en el lado izquierdo.
*/
private int numeroCanibalesDerecha;
/**
* Posicion 0: derecha, 1: izquierda.
*/
private int posicion;
/**
* Lista de estados hijos.
*/
private List<Estado> estados;

public Estado() {
}
public Estado(int numeroMisioneros, int numeroCanibales, int
posicion) {
this.numeroMisionerosIzquierda = numeroMisioneros;
this.numeroCanibalesIzquierda = numeroCanibales;
this.posicion = posicion;
}
public Estado(int numeroMisionerosIzquierda, int
numeroCanibalesIzquierda, int numeroMisionerosDerecha, int
numeroCanibalesDerecha, int posicion) {
this.numeroMisionerosIzquierda = numeroMisionerosIzquierda;
this.numeroCanibalesIzquierda = numeroCanibalesIzquierda;
this.numeroMisionerosDerecha = numeroMisionerosDerecha;
this.numeroCanibalesDerecha = numeroCanibalesDerecha;
this.posicion = posicion;
}
public void generarEstados() {
setEstados(new ArrayList<Estado>());
if (posicion == 1) {
enviar();
} else {
regresar();
}
}
public void enviar() {
List<Estado> es = new ArrayList<>();
Estado e1 = new Estado();
Estado e2 = new Estado();
Estado e3 = new Estado();
try {
e1 = this.clone();
e2 = this.clone();
e3 = this.clone();
} catch (CloneNotSupportedException ex) {
Logger.getLogger(Estado.class.getName()).log(Level.SEVERE,
null, ex);
}
if (numeroCanibalesIzquierda >= 2) {
e1.setNumeroCanibalesIzquierda(numeroCanibalesIzquierda - 2);
e1.setNumeroCanibalesDerecha(numeroCanibalesDerecha + 2);
e1.setPosicion(0);
es.add(e1);
}
if (numeroCanibalesIzquierda >= 1) {
if (numeroMisionerosIzquierda >= 1) {
e2.setNumeroCanibalesIzquierda(numeroCanibalesIzquierda 1);
e2.setNumeroMisionerosIzquierda(numeroMisionerosIzquierda
- 1);
e2.setNumeroCanibalesDerecha(numeroCanibalesDerecha + 1);

e2.setNumeroMisionerosDerecha(numeroMisionerosDerecha +
1);
e2.setPosicion(0);
es.add(e2);
}
}
if (numeroMisionerosIzquierda >= 2) {
e3.setNumeroMisionerosIzquierda(numeroMisionerosIzquierda 2);
e3.setNumeroMisionerosDerecha(numeroMisionerosDerecha + 2);
e3.setPosicion(0);
es.add(e3);
}
this.setEstados(es);
}
public void regresar() {
Estado e = new Estado();
Estado e2 = new Estado();
List<Estado> es = new ArrayList<>();
try {
e = this.clone();
e2 = this.clone();
} catch (CloneNotSupportedException ex) {
Logger.getLogger(Estado.class.getName()).log(Level.SEVERE,
null, ex);
}
if (numeroMisionerosDerecha > numeroCanibalesDerecha) {
e.setNumeroMisionerosDerecha(numeroMisionerosDerecha - 1);
e.setNumeroMisionerosIzquierda(numeroMisionerosIzquierda +
1);
e.setPosicion(1);
es.add(e);
e2.setNumeroCanibalesDerecha(numeroCanibalesDerecha - 1);
e2.setNumeroCanibalesIzquierda(numeroCanibalesIzquierda + 1);
e2.setPosicion(1);
es.add(e2);
} else if (numeroMisionerosDerecha == numeroCanibalesDerecha) {
e.setNumeroMisionerosDerecha(numeroMisionerosDerecha - 1);
e.setNumeroMisionerosIzquierda(numeroMisionerosIzquierda +
1);
e.setNumeroCanibalesDerecha(numeroCanibalesDerecha - 1);
e.setNumeroCanibalesIzquierda(numeroCanibalesIzquierda + 1);
e.setPosicion(1);
es.add(e);
} else {
e.setNumeroCanibalesDerecha(numeroCanibalesDerecha - 1);
e.setNumeroCanibalesIzquierda(numeroCanibalesIzquierda + 1);
e.setPosicion(1);
es.add(e);
}
this.setEstados(es);
}
@Override
public String toString() {
StringBuilder s = new StringBuilder();

s.append("M: ");
s.append(numeroMisionerosIzquierda);
s.append("; C: ");
s.append(numeroCanibalesIzquierda);
s.append(" | M: ");
s.append(numeroMisionerosDerecha);
s.append("; C: ");
s.append(numeroCanibalesDerecha);
s.append(" | Posicion: ");
s.append(posicion);
return s.toString();
}
@Override
protected Estado clone() throws CloneNotSupportedException {
try {
return (Estado) super.clone();
} catch (Exception e) {
throw new CloneNotSupportedException();
}
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Estado other = (Estado) obj;
if (this.numeroMisionerosIzquierda !=
other.numeroMisionerosIzquierda) {
return false;
}
if (this.numeroCanibalesIzquierda !=
other.numeroCanibalesIzquierda) {
return false;
}
if (this.numeroMisionerosDerecha !=
other.numeroMisionerosDerecha) {
return false;
}
if (this.numeroCanibalesDerecha != other.numeroCanibalesDerecha)
{
return false;
}
if (this.posicion != other.posicion) {
return false;
}
return true;
}
/**
* @return the numeroMisionerosIzquierda
*/
public int getNumeroMisionerosIzquierda() {

return numeroMisionerosIzquierda;
}
/**
* @param numeroMisionerosIzquierda the numeroMisionerosIzquierda to
set
*/
public void setNumeroMisionerosIzquierda(int
numeroMisionerosIzquierda) {
this.numeroMisionerosIzquierda = numeroMisionerosIzquierda;
}
/**
* @return the numeroCanibalesIzquierda
*/
public int getNumeroCanibalesIzquierda() {
return numeroCanibalesIzquierda;
}
/**
* @param numeroCanibalesIzquierda the numeroCanibalesIzquierda to
set
*/
public void setNumeroCanibalesIzquierda(int numeroCanibalesIzquierda)
{
this.numeroCanibalesIzquierda = numeroCanibalesIzquierda;
}
/**
* @return the numeroMisionerosDerecha
*/
public int getNumeroMisionerosDerecha() {
return numeroMisionerosDerecha;
}
/**
* @param numeroMisionerosDerecha the numeroMisionerosDerecha to set
*/
public void setNumeroMisionerosDerecha(int numeroMisionerosDerecha) {
this.numeroMisionerosDerecha = numeroMisionerosDerecha;
}
/**
* @return the numeroCanibalesDerecha
*/
public int getNumeroCanibalesDerecha() {
return numeroCanibalesDerecha;
}
/**
* @param numeroCanibalesDerecha the numeroCanibalesDerecha to set
*/
public void setNumeroCanibalesDerecha(int numeroCanibalesDerecha) {
this.numeroCanibalesDerecha = numeroCanibalesDerecha;
}
/**

* @return the posicion


*/
public int getPosicion() {
return posicion;
}
/**
* @param posicion the posicion to set
*/
public void setPosicion(int posicion) {
this.posicion = posicion;
}
/**
* @return the estados
*/
public List<Estado> getEstados() {
return estados;
}
/**
* @param estados the estados to set
*/
public void setEstados(List<Estado> estados) {
this.estados = estados;
}
}

You might also like