Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions busquedas.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,5 +283,30 @@ def busqueda_A_estrella(problema, heuristica):
@return Un objeto tipo Nodo con la estructura completa

"""
raise NotImplementedError('Hay que hacerlo de tarea \
(problema 2 en el archivo busquedas.py)')

problema.num_nodos = 0
nodo_inicial = Nodo(problema.x0)
# Cola de prioridad
frontera = []
heapq.heappush(frontera, (0, nodo_inicial))
# Nodos explorados para evitar repeticion
visitados = {problema.x0: 0}

# Se saca el nodo de menor costo hasta que se llega a la meta o la frontera este vacia, siguiendo
# f(n) = g(n) + h(n)

while frontera:
_, nodo = heapq.heappop(frontera)

if problema.es_meta(nodo.estado):
nodo.nodos_visitados = problema.num_nodos
return nodo

for hijo in nodo.expande(problema.modelo):
hijo.nodos_visitados = nodo.nodos_visitados + 1
if (hijo.estado not in visitados or
visitados[hijo.estado] > hijo.costo + heuristica(hijo)):
heapq.heappush(frontera, (hijo.costo + heuristica(hijo), hijo))
visitados[hijo.estado] = hijo.costo + heuristica(hijo)

return None # Si no hay solucion...
20 changes: 10 additions & 10 deletions ocho_puzzle.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,18 +156,18 @@ def probando(pos_ini):
print("Explorando {} nodos\n\n".format(solucion.nodos_visitados))

# # ------- A* con h1 -----------
# print("---------- Utilizando A* con h1 -------------")
# problema = Ocho_puzzle(pos_ini)
# solucion = busquedas.busqueda_A_estrella(problema, h_1)
# print(solucion)
# print("Explorando {} nodos".format(solucion.nodos_visitados))
print("---------- Utilizando A* con h1 -------------")
problema = Ocho_puzzle(pos_ini)
solucion = busquedas.busqueda_A_estrella(problema, h_1)
print(solucion)
print("Explorando {} nodos".format(solucion.nodos_visitados))

# # ------- A* con h2 -----------
# print("---------- Utilizando A* con h2 -------------")
# problema = Ocho_puzzle(pos_ini)
# solucion = busquedas.busqueda_A_estrella(problema, h_2)
# print(solucion)
# print("Explorando {} nodos".format(solucion.nodos_visitados))
print("---------- Utilizando A* con h2 -------------")
problema = Ocho_puzzle(pos_ini)
solucion = busquedas.busqueda_A_estrella(problema, h_2)
print(solucion)
print("Explorando {} nodos".format(solucion.nodos_visitados))


if __name__ == "__main__":
Expand Down
154 changes: 123 additions & 31 deletions problemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
# Desarrolla el modelo del Camión mágico
# ------------------------------------------------------------

class CamionMagico.busquedas.ModeloBusqueda):
"""
class CamionMagico(busquedas.ModeloBusqueda):
"""
---------------------------------------------------------------------------------
Supongamos que quiero trasladarme desde la posición discreta $1$ hasta
la posicion discreta $N$ en una vía recta usando un camión mágico.
Expand All @@ -31,25 +31,63 @@ class CamionMagico.busquedas.ModeloBusqueda):
----------------------------------------------------------------------------------

"""
def __init__(self):
raise NotImplementedError('Hay que hacerlo de tarea')
def __init__(self, n):
self.n = n

def acciones_legales(self, estado):
raise NotImplementedError('Hay que hacerlo de tarea')
acciones = []

if estado < self.n:
acciones.append("caminar")

if estado * 2 <= self.n:
acciones.append("camion")

return acciones

def sucesor(self, estado, accion):
raise NotImplementedError('Hay que hacerlo de tarea')
if accion == "caminar":
return estado + 1
elif accion == "camion":
return estado * 2

def costo_local(self, estado, accion):
raise NotImplementedError('Hay que hacerlo de tarea')
if accion == "caminar":
return 1
elif accion == "camion":
return 2

@staticmethod
def bonito(estado):
def bonito(self, estado):
"""
El prettyprint de un estado dado

"""
raise NotImplementedError('Hay que hacerlo de tarea')
linea = ["-"] * self.n

if 1<= estado <= self.n:
linea[estado - 1] = "X"

outpout = ""
output += "Posicion: " + str(estado) + "\n"
output += "Camino: "

for i in range(self.n):
if (i+1) % 5 == 0 or i == 0 or i == self.n - 1:
output += str(i + 1)
else:
output += linea[i]

output += "\n "
for i in range(self.n):
if (i + 1) % 5 == 0 or i == 0 or i == self.n - 1:
output += str(i + 1)
else:
output += " "


return output


# ------------------------------------------------------------
# Desarrolla el problema del Camión mágico
Expand All @@ -61,42 +99,93 @@ class PblCamionMágico(busquedas.ProblemaBusqueda):
punto $1$ hasta el punto $N$ en el menor tiempo posible.

"""
def __init__(self):
raise NotImplementedError('Hay que hacerlo de tarea')
def __init__(self, n):
modelo = CamionMagico(n)
estado_inicial = 1
meta = lambda x: x == n
super().__init__(estado_inicial, meta, modelo)


# ------------------------------------------------------------
# Desarrolla una política admisible.
# ------------------------------------------------------------

def h_1_camion_magico(nodo):
"""
DOCUMENTA LA HEURÍSTICA QUE DESARROLLES Y DA UNA JUSTIFICACIÓN
PLATICADA DE PORQUÉ CREES QUE LA HEURÍSTICA ES ADMISIBLE

"""
return 0

def heuristica_camion(n):
def h_1_camion_magico(nodo):
"""
La heuristica mas simple posible, el problema siempre se puede resolver
caminando, se busca el minimo de pasos caminando, que es la diferencia entre
la posicion actual y la posicion meta.
"""
estado = nodo.estado
if estado >= n:
return 0
pasos_caminar = n - estado
return pasos_caminar
return h_1_camion_magico

# ------------------------------------------------------------
# Desarrolla otra política admisible.
# Analiza y di porque piensas que es (o no es) dominante una
# respecto otra política
# ------------------------------------------------------------

def h_2_camion_magico(nodo):
"""
DOCUMENTA LA HEURÍSTICA DE DESARROLLES Y DA UNA JUSTIFICACIÓN
PLATICADA DE PORQUÉ CREES QUE LA HEURÍSTICA ES ADMISIBLE
def heuristica_camion_2(n):
def h_2_camion_magico(nodo):
"""
Esta heurística estima el número de pasos necesarios para llegar a la meta
considerando el uso del camión mágico. La idea es multiplicar la posición
actual por 2 hasta que se alcance o supere la posición meta. Luego, se
calcula el número de pasos caminando desde la posición actual hasta la meta.
Esta heurística es admisible porque nunca sobreestima el costo real para
llegar a la meta. En el peor de los casos, se camina desde la posición
actual hasta la meta, lo que es igual al costo real. En el mejor de los
casos, se utiliza el camión mágico para llegar a la meta en menos pasos.
La heurística es dominante respecto a la heurística anterior porque
considera el uso del camión mágico, que puede ser más eficiente que
caminar. En situaciones donde el camión mágico es útil, esta heurística
proporcionará un costo estimado menor que la heurística anterior.

"""
return 0
"""
estado = nodo.estado
if estado >= n:
return 0
# Estima el costo de llegar a la meta usando el camión mágico
pasos_caminar = n - estado
pasos_bus = 0
while estado < n:
estado *= 2
pasos_bus += 1
return min(pasos_caminar, pasos_bus)
return h_2_camion_magico

def heuristica_camion_3(n):
def h_3_camion_magico(nodo):
"""
Probando con una tercera heurística como la segunda pero sin
considerar el costo de caminar. Esta heurística estima el número de pasos
necesarios para llegar a la meta considerando solo el uso del camión mágico.

"""
estado = nodo.estado
if estado >= n:
return 0

# Numero de pasos para llegar a la meta usando el camión mágico
# multiplicando la posición actual por 2 hasta que se alcance o supere la meta
pasos_bus = 0
temp_estado = estado
while temp_estado < n:
temp_estado *= 2
pasos_bus += 1
return pasos_bus
return h_3_camion_magico

# ------------------------------------------------------------
# Desarrolla el modelo del cubo de Rubik
# ------------------------------------------------------------

class CuboRubik.busquedas.ModeloBusqueda):
class CuboRubik(busquedas.ModeloBusqueda):
"""
La clase para el modelo de cubo de rubik, documentación, no olvides poner
la documentación de forma clara y concisa.
Expand Down Expand Up @@ -186,7 +275,7 @@ def compara_metodos(problema, heuristica_1, heuristica_2):
print('Método'.center(12) + 'Costo'.center(18) + 'Nodos visitados'.center(20))
print('-' * 50 + '\n\n')
print('A* con h1'.center(12)
+ str(solucion1.costo).center(18)
+ str(solucion1.costo).center(20)
+ str(solucion1.nodos_visitados))
print('A* con h2'.center(12)
+ str(solucion2.costo).center(20)
Expand All @@ -199,11 +288,14 @@ def compara_metodos(problema, heuristica_1, heuristica_2):

# Compara los métodos de búsqueda para el problema del camión mágico
# con las heurísticas que desarrollaste
problema = PblCamionMágico( XXXXXXXXXX ) # <--- PONLE LOS PARÁMETROS QUE NECESITES
compara_metodos(problema, h_1_camion_magico, h_2_camion_magico)
problema = PblCamionMágico(10) # <--- PONLE LOS PARÁMETROS QUE NECESITES

h_1 = heuristica_camion(10)
h_2 = heuristica_camion_3(10)
compara_metodos(problema, h_1, h_2)

# Compara los métodos de búsqueda para el problema del cubo de rubik
# con las heurísticas que desarrollaste
problema = PblCuboRubik( XXXXXXXXXX ) # <--- PONLE LOS PARÁMETROS QUE NECESITES
compara_metodos(problema, h_1_problema_1, h_2_problema_1)
#problema = PblCuboRubik( XXXXXXXXXX ) # <--- PONLE LOS PARÁMETROS QUE NECESITES
#compara_metodos(problema, h_1_problema_1, h_2_problema_1)