Está en la página 1de 8

Práctico 2

1. Escriba un programa en pseudocódigo para los agentes basados en metas y


basados en utilidad.

En los autómatas basados en metas y en utilidades un estado puede estar asociado con
más de una regla. Esto es, la función REGLA_CONICIDENTA devuelve un conjunto de
reglas. Por la funcion REGLA_ACCION cada regla tiene asociada una acción. Si alguna de
esas acciones me lleva al estado objetivo selecciono esa acción en ambos autómatas. Sino
en el autómata basado en metas selecciona aleatoriamente cualquier regla y en el
autómata basado en utilidades selecciona la regla asociada a la acción con mayor utilidad.

función AGENTE-BASADO-EN-METAS(percepción) devuelve una acción


estático: estado, una descripción actual del estado del mundo
reglas, un conjunto de reglas condición-acción
acción, la acción más reciente, inicialmente ninguna
metas, los estados que son metas

estado ← ACTUALIZAR-ESTADO(estado, acción, percepción)


reglas ← REGLA-COINCIDENCIA(estado, reglas)
acciónes ← REGLA-ACCIÓN[reglas]
accion ← SELECCION-ACCION-META-O-ACCION-ALEATORIA
(acciones, metas)
devolver acción

En el autómata basado en utilidades selecciono la regla que tiene la acción con mayor
utilidad.

función AGENTE-BASADO-EN-UTILIDADES(percepción) devuelve una acción


estático: estado, una descripción actual del estado del mundo
reglas, un conjunto de reglas condición-acción
acción, la acción más reciente, inicialmente ninguna
metas, los estados que son metas
utilidad, función de utilidad

estado ← ACTUALIZAR-ESTADO(estado, acción, percepción)


reglas ← REGLA-COINCIDENCIA(estado, reglas)
acciónes ← REGLA-ACCIÓN[reglas]
accion ← SELECCION-ACCION-META-O-ACCION-UTILIDAD-MAYOR
(acciones, metas, utilidad)
devolver acción
2. Consideremos el ejemplo de la aspiradora, instancie los algoritmos propuestos en
el ejercicio 1 para el caso de la aspiradora (puede complejizar el problema todo lo que
quiera).

Una aspiradora basada en metas contra una aspiradora basada en utilidades.


Si el objetivo de una aspiradora es limpiar todas las baldosas de una habitación y las
acciones de la aspiradora son moverse y limpiar, entonces sólo tiene que limpiar las
baldosas que están sucias.

Si solo puede saber el estado de suciedad de las baldosas vecinas a la posición en que se
encuentra la aspiradora una estrategia es moverse a las baldosas vecinas que tienen más
suciedad y moverse en forma aleatoria si no hay ninguna baldosa vecina que esté sucia.

La figura de la aspiradora que tiene color es el agente basado en utilidades. La aspiradora


basada en metas esta en blanco y negro.

Existe la probabilidad de que la aspiradora se pasee todo el día dando vueltas y no


encuentre las baldosas que están sucias. Para solucionar este problema se puede
implementar algún algoritmo de búsqueda, como puede ser primero en profundidad, o
primero en anchura. De esta forma puedo estar seguro que en algún momento la aspiradora
limpiará todas las baldosas y puedo tener una cota máxima de los pasos que puede llevar
limpiar toda la habitación.
Evolución temporal de limpieza de las 2 aspiradoras en 102 pasos de simulación.

Cantidad total de baldosas limpiadas con 2 aspiradoras en 102 pasos de simulación.


3. Consideremos un termostato simple que enciende una caldera cuando la
temperatura está al menos tres grados por debajo de la temperatura seteada, y la
apaga cuando la temperatura está al menos 3 grados por encima de la temperatura
seteada. El termostato, ¿es una instancia de un agente reactive? ¿un agente basado
en metas?¿o un agente basado en utilidad?

El termostato es una instancia de un agente reactivo. Podemos. asumir que el ambiente del
termostato puede estar en uno de dos estados, muy frío o temperatura OK. El agente
termostato tiene dos subsistemas: uno es percepción y el otro acción.

Especificamos al agente termostato del siguiente modo:

Ag = {ver, acción}

La función ver le da al agente la capacidad de observar al ambiente:

ver : E - > Per


ver{e} = | “la temperatura del cuarto está OK” si e = temperatura OK
| “la temperatura del cuarto esta muy fria” si e= muy frío

La función acción realiza el proceso de toma de decisión:

action : Per* - > Ac


action{e} = | apagar caldera si e = “la temperatura del cuarto esta OK”
| encender caldera si e= “la temperatura del cuarto esta muy fria”

Podemos agregarle estado al agente termostato:

action: I -> Ac
next: I x Per -> I

El agente empieza con estado inicial i0, observa su ambiente y genera una percepción
ver(e). De esta forma el estado interno del agente es modificado por la función next de la
siguiente manera next(i0, ver(e)). Y la acción seleccionada por el agente es action(next(i0,
ver(e))

4. Implementar Algoritmo genérico de búsqueda (ver Slide 87 clase 2 parte 1)

Implementación en python de un algoritmo genérico de búsqueda. Dependiendo de cómo se


agrega y se saca un elemento del conjunto de estados a visitar obtenemos el algoritmo de
búsqueda primero en profundidad o primero a lo ancho. Si para los estados a visitar se usa
una pila (LIFO, Last In-First Out) obtenemos el algoritmo de búsqueda primero en
profundidad (DFS), si usamos una cola FIFO (First-In, First-Out) obtenemos el algoritmo de
búsqueda primero a lo ancho (BFS).

def busquedaGenerica(grafo, estadoInicial):


estadosVisitados = []
conjuntoDeEstados = []

estadosVisitados.append(estadoInicial)
conjuntoDeEstados.append(estadoInicial)

while conjuntoDeEstados:
s = conjuntoDeEstados.sacarUnElemento()
print (s, end = " ")

for unEstadoVecino in grafo[s]:


if unEstadoVecino not in estadosVisitados:
estadosVisitados.append(unEstadoVecino)
conjuntoDeEstados.append(unEstadoVecino)

5. Modifique mínimamente el algoritmo del punto anterior para implementar los


métodos de búsquedas “Primero en profundidad” y “Primero a lo ancho”.

Implementado en google collaboratory:


https://drive.google.com/file/d/1AyCyeaCJD82d6ISu_NC1lOzc6V9qs4Fm/view?usp=sharing

Si en el algoritmo genérico de búsqueda usamos una pila para los nodos que se tienen que
visitar implementamos la búsqueda primero en profundidad. Saco el nodo que está en el
tope de la pila y agregó todos sus hijos a la pila y recien que haya terminado de visitar todos
los hijos del que estaba en el tope de la pila seguir con el que estaba segundo en la pila
hace que siempre se expanda el nodo más profundo en la frontera actual del árbol de
búsqueda.

def busquedaPrimeroEnProfundidad(grafo, estadoInicial):


estadosVisitados = []
pilaDeEstados = []

estadosVisitados.append(estadoInicial)
pilaDeEstados.append(estadoInicial)

while pilaDeEstados:
s = pilaDeEstados.pop()
print (s, end = " ")

for unEstadoVecino in grafo[s]:


if unEstadoVecino not in estadosVisitados:
estadosVisitados.append(unEstadoVecino)
pilaDeEstados.append(unEstadoVecino)
Usar una cola en el algoritmo genérico de búsqueda implementa la búsqueda primero en
anchura. Agrego a la cola todos los hijos del nodo raíz. Selecciono uno de sus hijos, lo saco
de la cola y agregó todos sus hijos. Pero ahora, a diferencia del primero en profundidad, no
sigo con los hijos del hijo del nodo raíz, sino con los hermanos del hijo del nodo raíz. El
primero que está en la cola es un hermano del hijo del nodo raíz..

Implementado en google collaboratory:


https://drive.google.com/file/d/1AyCyeaCJD82d6ISu_NC1lOzc6V9qs4Fm/view?usp=sharing

def busquedaPrimeroEnAnchura(grafo, estadoInicial):


estadosVisitados = []
colaDeEstados = []

estadosVisitados.append(estadoInicial)
colaDeEstados.append(estadoInicial)

while colaDeEstados:
s = colaDeEstados.pop(0)
print (s, end = " ")

for unEstadoVecino in grafo[s]:


if unEstadoVecino not in estadosVisitados:
estadosVisitados.append(unEstadoVecino)
colaDeEstados.append(unEstadoVecino)

6. ¿Es el método de búsqueda “Iterative deeping” completo? ¿Por qué?

La búsqueda de profundidad simple no es completa porque se puede atascar en caminos


de profundidad infinita o en ciclos.

La búsqueda en profundidad limitada funciona igual que la búsqueda en profundidad simple


pero impone un límite máximo de profundidad a la búsqueda. Si el factor de ramificación es
finito entonces encuentra una solución si esta se encuentra dentro de los límites de la
profundidad, ya que no continua por caminos de profundidad infinita ni se atasca en ciclos.
Pero no es completo porque no encuentra una solución si esta se encuentra más allá del
límite de profundidad elegido.

La búsqueda en profundidad iterativa realiza una sucesiva búsqueda en profundidad


limitada incrementado el límite de profundidad en cada iteración hasta alcanzar la
profundidad del objetivo de menor profundidad. Es completo si el factor de ramificación es
finito porque como en la búsqueda de profundidad limitada no continua por caminos de
profundidad infinita ni se atasca en ciclos y al realizar sucesivas búsquedas en profundidad
imitada incrementar el límite de profundidad en cada paso si existe alguna solución a alguna
profundidad, con suficientes pasos de incremento de profundidad el algoritmo encuentra la
solución.

También podría gustarte