-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathentrega1.py
194 lines (141 loc) · 6.11 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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
from simpleai.search import SearchProblem, astar
tunel = [] # Aca guardamos los tuneles globalmente
def planear_escaneo(tuneles, robots):
'''
A partir de los tuneles y robots recibidos
como parametros, formulamos un estado,corremos
el problema con ese estado y devolvemos la estructura
de salida requerida
'''
INITIAL_STATE = formular_estado(robots, tuneles)
problema = MinaProblema(INITIAL_STATE)
resultado = astar(problema, graph_search=True)
salida = []
for action, state in resultado.path():
if action is not None:
salida.append(tuple(action))
return salida
def formular_estado(robots,tuneles):
'''A partir de los parametros recibidos creamos el estado inicial'''
global tunel
tunel = tuneles
robots_modificable = list(list(robot) for robot in robots)
for robot in robots_modificable:
robot.append((5,0)) #Agregamos la posicion inicial de cada robot
robot.append(1000) #Agregamos la bateria inicial de cada robot
robots = tuple(tuple(robot) for robot in robots_modificable)
pendientes = tuneles
state = (robots, pendientes)
return state
'''
INITIAL_STATE= ( ("s1", "soporte", (5,0), 1000),("s2", "soporte", (5,0),1000)), () )
robots recorridos
'''
class MinaProblema(SearchProblem):
def cost(self, state1, action, state2):
accion = action[1]
if accion == "mover":
return 1
elif accion == "cargar":
return 5
def is_goal(self, state):
_ , pendientes = state
if len(pendientes) == 0:
return True
else:
return False
def actions(self,state):
robots, _ = state
actions = []
for robot in robots:
if robot[3] >= 100:
#moverse dentro de tablero y si existe en tuneles
fila_robot, colu_robot = robot[2]
if (fila_robot-1,colu_robot) in tunel:
actions.append((robot[0],"mover",(fila_robot-1,colu_robot)))
if (fila_robot+1,colu_robot) in tunel:
actions.append((robot[0],"mover",(fila_robot+1,colu_robot)))
if (fila_robot,colu_robot-1) in tunel:
actions.append((robot[0],"mover",(fila_robot,colu_robot-1)))
if (fila_robot,colu_robot+1) in tunel:
actions.append((robot[0],"mover",(fila_robot,colu_robot+1)))
#si es robot Soporte recargar si hay robot Mapeadores en mismo ubicacion
if robot[1] == "soporte":
for robotMapeo in robots:
if robotMapeo[1] == "escaneador" and robot[2] == robotMapeo[2] and robotMapeo[3]<1000:
actions.append((robot[0],"cargar",robotMapeo[0]))
return actions
def result(self, state, action):
robots, pendientes = state
robot_origen, action_name, robot_destino = action
robots_m = list(list(robot) for robot in robots)
pendientes_m = list(pendientes)
if action_name == "mover":
robot = [robot for robot in robots_m if robot[0] == robot_origen][0]
robot[2] = robot_destino
if robot[1] == "escaneador":
robot[3] = robot[3] - 100
if robot[2] in pendientes_m:
pendientes_m.remove(robot[2])
else:
robot = [robot for robot in robots_m if robot[0] == robot_destino][0]
robot[3] = 1000
robots = tuple(tuple(robot) for robot in robots_m)
pendientes = tuple(pendientes_m)
nuevo_state = (robots, pendientes)
'''
Este codigo tarda 2 minutos menos que el de arriba. al final la compresion de listas
gasta mas que un for comun!!!!
if action_name == "mover":
# si action = mover y rMapeo -> descontar bateria 100 y agregar en casilleros recorridos, si es rSoporte solo cambiar posicion
for robot in robots_m:
if robot[0] == robot_origen:
robot[2] = robot_destino
if robot[1] == "escaneador":
robot[3] = robot[3] - 100
if robot[2] in pendientes_m:
pendientes_m.remove(robot[2])
break
break
else: # si action = recargar -> recargar bateria de robot especificado a 1000
for robot in robots_m:
if robot[0] == robot_destino:
robot[3] = 1000
break
robots = tuple(tuple(robot) for robot in robots_m)
pendientes = tuple(pendientes_m)
nuevo_state = (robots, pendientes)
'''
return nuevo_state
def heuristic(self, state):
'''
Distancia minima a la que se encuentra el robot
mas cercano a cada posicion pendiente de recorrer.
Si un robot tiene mas de una posicion pendiente
cerca, tomamos la mas lejana.
robots = state[0]
recorrido_m = list(state[1])
faltan_recorrer = list(set(tunel)-set(recorrido_m))
robots_m = list(list(robot)for robot in robots)
for robot in robots_m:
robot.append([])
for x_c, y_c in faltan_recorrer:
min = 999
robot_min = ""
for robot in robots_m:
if robot[1] is not "soporte":
x_r, y_r = robot[2]
diferencia = (abs((x_c-x_r)+(y_c-y_r)))
if diferencia<min:
min=diferencia
robot_min=robot
robot_min[4].append(min)
suma = 0
for robot in robots_m:
id,nombre, pos, bat, mins = robot
if len(mins)>0:
suma = suma + max(mins)
return suma
'''
robots , pendientes = state
return len(pendientes)