ASPIRADORA
Análisis general
Disponemos de un mundo en el que habitan dos agentes. Este mundo es un recinto cerrado en forma de cuadrícula de tamaño nxn, en el que cada casilla podrá tener suciedad, un obstáculo o nada (zona de paso). Los agentes poseen dos sensores, uno de suciedad y otro de choque y cuatro efectores, para moverse en las cuatro direcciones cardinales, y tienen la misión de succionar más cantidad de suciedad que el adversario. El mundo está compuesto por casillas vacías con o sin suciedad y por obstáculos, las primeras podrán ser recorridas y limpiadas por los agentes, mientras que los obstáculos, no podrán ser atravesados. Además, el mundo no es estocástico, ya que la suciedad y distribución de obstáculos en él es determinada al principio y sólo varía por la acción de los agentes, acciones que ambos agentes conocerán en todo momento. Cada agente conoce a priori el mapa del mundo, incluyendo la distribución de muros y casillas sucias. También sabe el grado de suciedad que tienen las casillas sucias, medido en números enteros crecientes, empezando en 0 para casillas limpias. En esta ocasión nuestros agentes tienen la habilidad de succionar la suciedad de una casilla con sólo pasar sobre ella, por contra, dejarán un rastro en cada casilla que han atravesado de forma que esa casilla no puede ser visitada de nuevo por ninguno de los dos agentes. La percepción del tiempo para los agentes es discreta y sólo podrán realizar un movimiento en turnos alternos, a no ser que algún agente quede bloqueado sin poder moverse.
Solución propuesta Hemos diseñado un agente reactivo con memoria y a la vez un agente de búsqueda en profundidad, el agente posee un vector de características con las siguientes componentes:
Coordenada X del agente en el mapa interno.
Coordenada Y del agente en el mapa interno.
Último movimiento realizado.
Para la toma de decisiones, el agente hace uso de los sensores de percepción y de varios Módulos de Conocimiento que determinarán la acción a realizar. Básicamente, el funcionamiento del agente consiste en repetir los siguientes pasos:
Llamar a los Módulos de Conocimiento "actualizarMapa" y "actualizarPos" para actualizar la representación interna del mundo según el estado del sensor de choque y la posición del agente.
Comprobar si el sensor de suciedad se ha activado, en caso afirmativo, limpiar la casilla.
Si la casilla está limpia, el agente llamará al Módulo de Conocimiento "modoExploracion" que buscará en la representación interna si una de las cuatro posibles casillas a las que el agente puede desplazarse en el próximo turno no ha sido nunca explorada. En caso afirmativo se desplazará a esa posición.
Si las cuatro casillas están exploradas, el "modoExploracion" indicará al agente que permanezca inactivo, en ese caso el agente acudirá al segundo Módulo de Conocimiento denominado "modoMasAntigua" que buscará en la representación interna la casilla de su alrededor (de las cuatro posibles) que lleve más tiempo sin visitar y que no sea un muro. Finalmente indicará al agente que se mueva en la dirección oportuna.
La razón de aplicar este comportamiento es que como no podemos saber qué casilla se ensucia más o menos puesto que es aleatorio, el agente tratará siempre de ir hacia casillas que lleven más tiempo sin ser visitadas y, por tanto, que tengan mayor probabilidad de estar sucias. Este algoritmo, a pesar de ser muy sencillo, es bastante eficaz.
Estructura Interna del Agente void actualizarMapa() Módulo que actualiza el mapa interno según la posición y el estado del sensor de choque "bump_". Además, cada casilla que ya esté descubierta se incrementa en 1, reflejando así el número de turnos que el agente no ha pasado por dicha casilla (antigüedad). Por lo tanto, existen una serie de valores posibles para cada casilla del mapa, que son:
-1 : Casilla que nunca ha sido visitada (sin explorar).
0 : Muro. 1 : Última casilla visitada (debe ser un hueco). >1 : Casilla visitada hace n turnos (debe ser un hueco).
En el proceso de actualización del mapa, llama a buscarLimites() para intentar descubrir los límites del mapa.
void actualizarPos(int direccion) Actualiza las coordenadas del agente según la dirección que va a tomar. Además, almacena el movimiento como el último que ha hecho. NOTA: Este módulo debe ejecutarse después de decidir qué acción va a realizarse pero antes de realizar el movimiento.
void buscarLimites() Recorre la matriz interna para buscar los límites del mapa (perímetro) y, si los encuentra, los marca como muros. Basta con encontrar 2 huecos separados entre sí 6 filas o 2 huecos separados 6 columnas. Se puede hacer aprovechando que se sabe que es un recinto cerrado de 10x10. Este módulo no ofrece una gran mejora de eficacia y sólo es útil en mapas en los que el agente puede chocar contra los cuatro lados del perímetro del mapa. Pero se deja activo ya que está hecho y funciona.
int modoExploracion() Busca una casilla sin explorar de las cuatro posibles de alrededor del agente (los cuatro puntos cardinales). Devuelve la acción que debe realizar el agente para ir a la casilla sin explorar o "actIDLE" en caso de que las cuatro posibles casillas hayan sido ya exploradas. En caso de que haya más de una casilla sin explorar, se aplicarán las siguientes reglas, en orden de prioridad:
La casilla sin explorar está en la misma dirección tomada el turno anterior. La casilla sin explorar está arriba.
La casilla sin explorar está abajo.
La casilla sin explorar está a la izquierda.
La casilla sin explorar está a la derecha.
En caso de que las cuatro casillas ya estén exploradas el módulo devuelve "actIDLE".
int modoMasAntigua() Busca la casilla que haya sido visitada al menos una vez y que más tiempo lleve sin visitar de las cuatro posibles de alrededor del agente. Devuelve el movimiento a realizar para ir a esa casilla.
void Think() Es el módulo principal del agente, se encarga de llamar al resto de módulos para determinar la acción a realizar. Su funcionamiento ya ha sido explicado en la sección "Descripción de la Solución Propuesta". Ahora se tendrá que usar una interfaz gráfica para poder observar la realización del programa gráficamente: Utilizaremos el algoritmo MINIMAX Se ha aplicado el clásico algoritmo Mini Max con una pequeña variación:
Si el nivel de profundidad es menor que 10.
Generar posibles movimientos.
Si se está en un nodo Max, tomar el movimiento generado con mayor valor heurístico.
Si se está en un nodo Min, tomar el movimiento generado con menor valor heurístico.
Si no se ha generado ningún movimiento, significará que el agente no se puede mover. Por tanto, tomar el valor que retorne de aplicar el algoritmo al estado actual, cambiando el turno del jugador.
Si el nivel de profundidad es 10 o más.
Aplicar la función heurística para el estado actual y el jugador que llamó por primera vez al algoritmo.
Devolver el movimiento elegido por Max.
Heurística La heurística usada utiliza tres parámetros ponderados:
Distancia manhattan desde el agente al punto sucio más cercano, con una ponderación de 0.59.
Número de muros alrededor del agente, sólo contando los cuatro puntos cardinales, tiene una ponderación de 0.19.
Número de veces que ha estado el agente en esa posición (envejecimiento) contando desde la última casilla limpia. Esto quiere decir que cuando se limpia una casilla se reinician los contadores de todas las casillas visitadas. Se ha puesto 0.22 de ponderación.
Conclusiones:
Elegimos el agente reactivo con memoria, cuyo único conocimiento inicial del entorno es que se está en un recinto cerrado de 10x10 casillas que se ensucian de forma aleatoria. El robot debe maximizar la suciedad aspirada y minimizar el consumo.
Usamos el agente deliberativo que use búsqueda en profundidad con conocimiento de la localización de la suciedad y de los muros de un recinto de tamaño NxN. El robot debe maximizar el número de casillas limpiadas y minimizar el consumo.
Creamos un agente deliberativo que use búsqueda basada en un método de escalada con conocimiento de la localización de la suciedad y de los muros de un recinto de tamaño NxN. El robot debe maximizar el número de casillas limpiadas y minimizar el consumo.
Elaboramos un
agente deliberativo que use búsqueda MINIMAX con profundidad
limitada. Este agente estará en el entorno (conocido) con otro agente aspiradora y debe tratar de aspirar más suciedad que su rival. Además, para este problema en concreto, los agentes dejan una estela por las casillas que atraviesan, impidiendo que se vuelva a poder pasar por ellas.
Estructura