/
entrega1.py
158 lines (120 loc) · 5.12 KB
/
entrega1.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
from simpleai.search import SearchProblem
from simpleai.search import breadth_first, depth_first, greedy, astar
from simpleai.search.viewers import WebViewer, ConsoleViewer, BaseViewer
def ValidarMovimiento(accion, camino):
#Valida que no pueda moverme a una posicion por la que ya pase
return accion not in camino
def RobotEnOrilla(pos):
if pos[0] == 5 or pos[1] == 5 or pos[0] == 0 or pos[1] == 0:
return True
else:
return False
def DistanciaOrillaCercana(pos):
#Dada una posicion, busca la menor distancia a una orilla
fila, columna = pos
menorDistancia = 5
if abs(0 - fila) < menorDistancia:
menorDistancia = abs(0-fila)
if abs(5 - fila) < menorDistancia:
menorDistancia = abs(5-fila)
if abs(0 - columna) < menorDistancia:
menorDistancia = abs(0-columna)
if abs(5 - columna) < menorDistancia:
menorDistancia = abs(5-columna)
return menorDistancia
def GenerarEstado(personas):
# [[Posicion del robot], [Camino por donde ya pase], [Posicion de las personas], [Si el robot carga o no personas]]
estado = [(0, 0), (), personas, 0]
return tuple(estado)
class RescateHieloProblem(SearchProblem):
def cost(self, state, action, state2):
return 1
def is_goal(self, state):
#Valida que el robot no este cargarndo a nadie, y no queden personas por rescatar
personas = len(state[2])
cargado = state[3]
if cargado == 0 and personas == 0:
return True
else:
return False
def actions(self, state):
acciones_disponibles = []
state = list(state)
pos = state[0]
fila = pos[0]
columna = pos[1]
caminoRecorrido = state[1]
posNueva = ()
if fila > 0: #arriba
posNueva = (fila-1, columna)
if ValidarMovimiento(posNueva, caminoRecorrido):
acciones_disponibles.append(posNueva)
if fila < 5: #abajo
posNueva = (fila+1, columna)
if ValidarMovimiento(posNueva, caminoRecorrido):
acciones_disponibles.append(posNueva)
if columna > 0: #izquierda
posNueva = (fila, columna-1)
if ValidarMovimiento(posNueva, caminoRecorrido):
acciones_disponibles.append(posNueva)
if columna < 5: # derecha
posNueva = (fila, columna + 1)
if ValidarMovimiento(posNueva, caminoRecorrido):
acciones_disponibles.append(posNueva)
return acciones_disponibles
def result(self, state, action):
camino = list(state[1])
personas = list(state[2])
cargado = state[3]
if RobotEnOrilla(action):
cargado = 0
else:
camino.append(action)
if action in personas:
personas.remove(action)
cargado = 1
#estado = (action, camino, personas, cargado)
estado = action, tuple(camino), tuple(personas), cargado
return estado
def heuristic(self, state):
'''Calculo la suma de la distancia del robot hasta la persona mas lejana,
+ la distancia hasta la orilla mas cercana, + la cantidad de personas restantes'''
filaRobot, columnaRobot = state[0]
posicionPersonas = list(state[2])
distanciaMax = 0
posicionMasLejano = []
if len(posicionPersonas)> 0:
#Distancia hasta persona mas lejana + distancia orilla cercana + personas restantes
for p in posicionPersonas:
distancia = abs(filaRobot - p[0]) + abs(columnaRobot - p[1])
if distancia > distanciaMax:
distanciaMax = distancia
posicionMasLejano = (p[0], p[1])
posicionPersonas.remove(posicionMasLejano)
distanciaSalida = DistanciaOrillaCercana(posicionMasLejano)
return distanciaMax + distanciaSalida + len(posicionPersonas)
else:
#No quedan personas por rescatar. Distancia hasta la orilla mas cercana
return DistanciaOrillaCercana((filaRobot,columnaRobot))
def resolver(metodo_busqueda, posiciones_personas):
inicial = GenerarEstado(posiciones_personas)
problema = RescateHieloProblem(inicial)
if metodo_busqueda == "breadth_first":
return breadth_first(problema, graph_search=True, viewer=ConsoleViewer())
if metodo_busqueda == "greedy":
return greedy(problema, graph_search=True, viewer=ConsoleViewer())
if metodo_busqueda == "depth_first":
return depth_first(problema, graph_search=True, viewer=ConsoleViewer())
if metodo_busqueda == "astar":
return astar(problema, graph_search=True, viewer=ConsoleViewer())
if __name__ == '__main__':
Inicial = GenerarEstado(((2, 1), (3, 4), (4, 2)))
problema = RescateHieloProblem(Inicial)
print('Prueba astar')
visor = BaseViewer()
resultado = astar(problema, graph_search = True, viewer = visor)
#print("path:", resultado.path())
print("Profundidad:", len(resultado.path()))
print("Estado:", resultado.state)
print("Costo:", resultado.cost)
print("Estadisticas:" , visor.stats)