-
Notifications
You must be signed in to change notification settings - Fork 0
/
djikstra_DarshitMiteshkumar_Desai.py
329 lines (304 loc) · 12.6 KB
/
djikstra_DarshitMiteshkumar_Desai.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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
# import the pygame module
import pygame as pyg
import numpy as np
#import queue module
from queue import PriorityQueue
import time
#Note: All obstacle dimensions are inflated to cover the point robot radius of 5 mm or 5 pixels. You will see the
#same in the visualisation
#Define the Surface Map
screen = pyg.Surface((600, 250))
#Define the rectangles which make the base map
rect_color = (255, 255, 255)
#Define the rectangle which makes the outer border
rectangle1 = pyg.Rect(5, 5, 590, 240)
screen.fill((255,0,0))
pyg.draw.rect(screen, rect_color, rectangle1)
#Define the rectangle which makes the 2 rectangles
pyg.draw.rect(screen, (255,0,0),pyg.Rect(95,145,60,105))
pyg.draw.rect(screen, (255,0,0),pyg.Rect(95,0,60,105))
#Define the hexagon in the center
hexagon_dim = [(300,44.22649731),(230.04809472,84.61324865),(230.04809472,165.38675135),(300,205.77350269),(369.95190528,165.38675135),(369.95190528,84.61324865)]
pyg.draw.polygon(screen,(255,0,0),hexagon_dim)
triangle_dim = [(455,246.18033989),(455.00,3.81966011),(515.59016994,125)]
pyg.draw.polygon(screen,(255,0,0),triangle_dim)
# Set the caption of the screen
pyg.display.set_caption('Djikstra')
# Variable to keep our game loop running
running = True
#Condition which asks the user for their inputs
while True:
start_x = int(input("Please enter the x coordinate of start:"))
start_y = int(input("Please enter the y coordinate of start:"))
goal_x = int(input("Please enter the x coordinate of goal:"))
goal_y = int(input("Please enter the y coordinate of goal:"))
start_y = 250-(start_y)
goal_y = 250-(goal_y)
if (screen.get_at((goal_x,goal_y))!=(255,0,0,255) and screen.get_at((start_x,start_y))!=(255,0,0,255) and (start_x<600 or start_x>0) and (start_y>0 or start_y<250)and(goal_x<600 or goal_x>0) and (goal_y>0 or goal_y<250)):
print("Valid coordinates received")
break
else:
print("Invalid coordinates try again")
#Djikstra Starts here
#Start time to measure time of run of algorithm
start_time = time.time()
#Definitions of initial conditions of Djikstra like start node goal node indices
start_node = (start_x,start_y)
goal_node = (goal_x,goal_y)
Node_i = 0
Parent_Node_i = -1
initial_c2c = 0
node_state=[initial_c2c, Node_i, Parent_Node_i, start_node]
index=None
Open_list = PriorityQueue()
Open_list.put(node_state)
Closed_list = {}
goalreached = 0
#Action set function which updates coordinates and actions
def gen_up(node,nc2c):
nnode = (node[0]+0,node[1]-1)
cost = nc2c+1
return nnode, cost
def gen_down(node,nc2c):
nnode = (node[0]+0,node[1]+1)
cost = nc2c+1
return nnode, cost
def gen_left(node,nc2c):
nnode = (node[0]-1,node[1]+0)
cost = nc2c+1
return nnode, cost
def gen_right(node,nc2c):
nnode = (node[0]+1,node[1]+0)
cost = nc2c+1
return nnode, cost
def gen_up_left(node, nc2c):
nnode = (node[0]-1,node[1]-1)
cost = nc2c + 1.4
return nnode, cost
def gen_up_right(node, nc2c):
nnode = (node[0]+1,node[1]-1)
cost = nc2c + 1.4
return nnode, cost
def gen_down_left(node, nc2c):
nnode = (node[0]-1,node[1]+1)
cost = nc2c + 1.4
return nnode, cost
def gen_down_right(node, nc2c):
nnode = (node[0]+1,node[1]+1)
cost = nc2c + 1.4
return nnode, cost
#Parent Node incremented to be ready for the next node
Parent_Node_i+=1
#Variable used for tracking goal node index
gni=None
#Main iterator starts
while (Open_list.empty()==False):
#Pop the first node of open list
nodegen = Open_list.get()
nodecoord = nodegen[-1]
nodec2c = nodegen[0]
Closed_list[nodegen[1]]=[nodec2c,nodegen[2],nodecoord]
print("Latest generated node:",nodegen)
#Check whether we found the goal node or not
if(nodecoord==goal_node):
print("Woohoo we reached the goal")
goalreached=1
gni=nodegen[1]
gnc=nodecoord
break
#Assign the latest popped node index as parent node
Parent_Node_i=nodegen[1]
#Code which generates and checks the up action coordinates for validity to update in open list or modify the cost
new_node_up, new_node_cost_up = gen_up(nodecoord, nodec2c)
if (new_node_up==goal_node):
Node_i+=1
gni = Node_i
Closed_list[Node_i]=[new_node_cost_up,Parent_Node_i,new_node_up]
print("Goal Reached after doing up operation")
goalreached=1
break
if (screen.get_at(new_node_up)!=(255, 0, 0, 255)):
if not(any(val[-1] == new_node_up for val in Closed_list.values())): #Check if in closed list
if new_node_up not in [tup[3] for tup in Open_list.queue]: #Check if in open list
Node_i+=1
temp_state = [new_node_cost_up, Node_i, Parent_Node_i, new_node_up]
Open_list.put(temp_state)
else:
index = next(i for i, (_, _, _, (x, y)) in enumerate(Open_list.queue) if (x, y) == new_node_up)
if (round(new_node_cost_up,1)<round(Open_list.queue[index][0],1)): #if in open list update cost
Open_list.queue[index][0]=new_node_cost_up
Open_list.queue[index][2]=nodegen[2]
#Code which generates and checks the down action coordinates for validity to update in open list or modify the cost
new_node_down, new_node_cost_down = gen_down(nodecoord, nodec2c)
if (new_node_down==goal_node):
Node_i+=1
gni = Node_i
Closed_list[Node_i]=[new_node_cost_down,Parent_Node_i,new_node_down]
print("Goal Reached after doing down operation")
goalreached=1
break
if (screen.get_at(new_node_down)!=(255, 0, 0, 255)):
if not(any(val[-1] == new_node_down for val in Closed_list.values())):
if new_node_down not in [tup[3] for tup in Open_list.queue]:
Node_i+=1
temp_state = [new_node_cost_down, Node_i, Parent_Node_i, new_node_down]
Open_list.put(temp_state)
else:
index = next(i for i, (_, _, _, (x, y)) in enumerate(Open_list.queue) if (x, y) == new_node_down)
if (round(new_node_cost_down,1)<round(Open_list.queue[index][0],1)):
Open_list.queue[index][0]=new_node_cost_down
Open_list.queue[index][2]=nodegen[2]
#Code which generates and checks the left action coordinates for validity to update in open list or modify the cost
new_node_left, new_node_cost_left = gen_left(nodecoord, nodec2c)
if (new_node_left==goal_node):
Node_i+=1
gni = Node_i
Closed_list[Node_i]=[new_node_cost_left,Parent_Node_i,new_node_left]
print("Goal Reached after doing left operation")
goalreached=1
break
if (screen.get_at(new_node_left)!=(255, 0, 0, 255)):
if not(any(val[-1] == new_node_left for val in Closed_list.values())):
if new_node_left not in [tup[3] for tup in Open_list.queue]:
Node_i+=1
temp_state = [new_node_cost_left, Node_i, Parent_Node_i, new_node_left]
Open_list.put(temp_state)
else:
index = next(i for i, (_, _, _, (x, y)) in enumerate(Open_list.queue) if (x, y) == new_node_left)
if (round(new_node_cost_left,1)<round(Open_list.queue[index][0],1)):
Open_list.queue[index][0]=new_node_cost_left
Open_list.queue[index][2]=nodegen[2]
#Code which generates and checks the right action coordinates for validity to update in open list or modify the cost
new_node_right, new_node_cost_right = gen_right(nodecoord, nodec2c)
if (new_node_right==goal_node):
Node_i+=1
gni = Node_i
Closed_list[Node_i]=[new_node_cost_right,Parent_Node_i,new_node_right]
print("Goal Reached after doing right operation")
goalreached=1
break
if (screen.get_at(new_node_right)!=(255, 0, 0, 255)):
if not(any(val[-1] == new_node_right for val in Closed_list.values())):
if new_node_right not in [tup[3] for tup in Open_list.queue]:
Node_i+=1
temp_state = [new_node_cost_right, Node_i, Parent_Node_i, new_node_right]
Open_list.put(temp_state)
else:
index = next(i for i, (_, _, _, (x, y)) in enumerate(Open_list.queue) if (x, y) == new_node_right)
if (round(new_node_cost_right,1)<round(Open_list.queue[index][0],1)):
Open_list.queue[index][0]=new_node_cost_right
Open_list.queue[index][2]=nodegen[2]
#Code which generates and checks the up left action coordinates for validity to update in open list or modify the cost
new_node_up_left, new_node_cost_up_left = gen_up_left(nodecoord, nodec2c)
if (new_node_up_left==goal_node):
Node_i+=1
gni = Node_i
Closed_list[Node_i]=[new_node_cost_up_left,Parent_Node_i,new_node_up_left]
print("Goal Reached after doing up left operation")
goalreached=1
break
if (screen.get_at(new_node_up_left)!=(255, 0, 0, 255)):
if not(any(val[-1] == new_node_up_left for val in Closed_list.values())):
if new_node_up_left not in [tup[3] for tup in Open_list.queue]:
Node_i+=1
temp_state = [new_node_cost_up_left, Node_i, Parent_Node_i, new_node_up_left]
Open_list.put(temp_state)
else:
index = next(i for i, (_, _, _, (x, y)) in enumerate(Open_list.queue) if (x, y) == new_node_up_left)
if (round(new_node_cost_up_left,1)<round(Open_list.queue[index][0],1)):
Open_list.queue[index][0]=new_node_cost_up_left
Open_list.queue[index][2]=nodegen[2]
#Code which generates and checks the up right action coordinates for validity to update in open list or modify the cost
new_node_up_right, new_node_cost_up_right = gen_up_right(nodecoord, nodec2c)
if (new_node_up_right==goal_node):
Node_i+=1
gni = Node_i
Closed_list[Node_i]=[new_node_cost_up_right,Parent_Node_i,new_node_up_right]
print("Goal Reached after doing up right operation")
goalreached=1
break
if (screen.get_at(new_node_up_right)!=(255, 0, 0, 255)):
if not(any(val[-1] == new_node_up_right for val in Closed_list.values())):
if new_node_up_right not in [tup[3] for tup in Open_list.queue]:
Node_i+=1
temp_state = [new_node_cost_up_right, Node_i, Parent_Node_i, new_node_up_right]
Open_list.put(temp_state)
else:
index = next(i for i, (_, _, _, (x, y)) in enumerate(Open_list.queue) if (x, y) == new_node_up_right)
if (round(new_node_cost_up_right,1)<round(Open_list.queue[index][0],1)):
Open_list.queue[index][0]=new_node_cost_up_right
Open_list.queue[index][2]=nodegen[2]
#Code which generates and checks the down left action coordinates for validity to update in open list or modify the cost
new_node_down_left, new_node_cost_down_left = gen_down_left(nodecoord, nodec2c)
if (new_node_down_left==goal_node):
Node_i+=1
gni = Node_i
Closed_list[Node_i]=[new_node_cost_down_left,Parent_Node_i,new_node_down_left]
print("Goal Reached after doing down left operation")
goalreached=1
break
if (screen.get_at(new_node_down_left)!=(255, 0, 0, 255)):
if not(any(val[-1] == new_node_down_left for val in Closed_list.values())):
if new_node_down_left not in [tup[3] for tup in Open_list.queue]:
Node_i+=1
temp_state = [new_node_cost_down_left, Node_i, Parent_Node_i, new_node_down_left]
Open_list.put(temp_state)
else:
index = next(i for i, (_, _, _, (x, y)) in enumerate(Open_list.queue) if (x, y) == new_node_down_left)
if (round(new_node_cost_down_left,1)<round(Open_list.queue[index][0],1)):
Open_list.queue[index][0]=new_node_cost_down_left
Open_list.queue[index][2]=nodegen[2]
#Code which generates and checks the down right action coordinates for validity to update in open list or modify the cost
new_node_down_right, new_node_cost_down_right = gen_down_right(nodecoord, nodec2c)
if (new_node_down_right==goal_node):
Node_i+=1
gni = Node_i
Closed_list[Node_i]=[new_node_cost_down_right,Parent_Node_i,new_node_down_right]
print("Goal Reached after doing down right operation")
goalreached=1
break
if (screen.get_at(new_node_down_right)!=(255, 0, 0, 255)):
if not(any(val[-1] == new_node_down_right for val in Closed_list.values())):
if new_node_down_right not in [tup[3] for tup in Open_list.queue]:
Node_i+=1
temp_state = [new_node_cost_down_right, Node_i, Parent_Node_i, new_node_down_right]
Open_list.put(temp_state)
else:
index = next(i for i, (_, _, _, (x, y)) in enumerate(Open_list.queue) if (x, y) == new_node_down_right)
if (round(new_node_cost_down_right,1)<round(Open_list.queue[index][0],1)):
Open_list.queue[index][0]=new_node_cost_down_right
Open_list.queue[index][2]=nodegen[2]
#Path Backtracking
path=[]
if (goalreached!=0):
while gni!=-1:
path.append(Closed_list[gni][-1])
gni=Closed_list[gni][1]
else:
print("Goal not reached")
path.reverse()
print(path)
end_time = time.time() #Algorithm end time
total_time = end_time - start_time
print(f"Total runtime: {total_time:.2f} seconds") #Final runtime
#Overlay the final canvas and display the pygame simulation
s1 = pyg.display.set_mode((600, 250))
# Blit the surface onto the Pygame window
s1.blit(screen, (0, 0))
# Update the display
pyg.display.update()
for valu in Closed_list.values():
s1.set_at(valu[-1],(255,0,255))
pyg.display.update()
if goalreached != 0:
for co in path:
s1.set_at(co,(0,0,0))
pyg.time.wait(50)
pyg.display.update()
pyg.time.wait(1000)
while running:
# for loop through the event queue
for event in pyg.event.get():
# Check for QUIT event
if event.type == pyg.QUIT:
running = False