1
+ import heapq
2
+ import numpy as np
3
+ import math
4
+ import copy
5
+
6
+
7
+ class PriorityQueue :
8
+ def __init__ (self ):
9
+ self .elements = []
10
+ self .set = set ()
11
+
12
+ def minkey (self ):
13
+ if not self .empty ():
14
+ return self .elements [0 ][0 ]
15
+ else :
16
+ return float ('inf' )
17
+
18
+ def empty (self ):
19
+ return len (self .elements ) == 0
20
+
21
+ def put (self , item , priority ):
22
+ if item not in self .set :
23
+ heapq .heappush (self .elements , (priority , item ))
24
+ self .set .add (item )
25
+ else :
26
+ # update
27
+ # print("update", item)
28
+ temp = []
29
+ (pri , x ) = heapq .heappop (self .elements )
30
+ while x != item :
31
+ temp .append ((pri , x ))
32
+ (pri , x ) = heapq .heappop (self .elements )
33
+ temp .append ((priority , item ))
34
+ for (pro , xxx ) in temp :
35
+ heapq .heappush (self .elements , (pro , xxx ))
36
+
37
+ def remove_element (self , item ):
38
+ if item in self .set :
39
+ self .set .remove (item )
40
+ temp = []
41
+ (pro , x ) = heapq .heappop (self .elements )
42
+ while x != item :
43
+ temp .append ((pro , x ))
44
+ (pro , x ) = heapq .heappop (self .elements )
45
+ for (prito , yyy ) in temp :
46
+ heapq .heappush (self .elements , (prito , yyy ))
47
+
48
+ def top_show (self ):
49
+ return self .elements [0 ][1 ]
50
+
51
+ def get (self ):
52
+ (priority , item ) = heapq .heappop (self .elements )
53
+ self .set .remove (item )
54
+ return (priority , item )
55
+
56
+ def consistent_hueristic (P , goal ):
57
+ # euclidean distance
58
+ a = np .array (P )
59
+ b = np .array (goal )
60
+ return np .linalg .norm (a - b )
61
+
62
+ def hueristic_2 (P , goal ):
63
+ # integer division by time variable
64
+ return consistent_hueristic (P , goal ) // t
65
+
66
+ def hueristic_1 (P , goal ):
67
+ # manhattan distance
68
+ return abs (P [0 ] - goal [0 ]) + abs (P [1 ] - goal [1 ])
69
+
70
+ def key (start , i , goal , g_function ):
71
+ ans = g_function [start ] + W1 * hueristics [i ](start , goal )
72
+ return ans
73
+
74
+ def do_something (back_pointer , goal , start ):
75
+ grid = np .chararray ((n , n ))
76
+ for i in range (n ):
77
+ for j in range (n ):
78
+ grid [i ][j ] = '*'
79
+
80
+ for i in range (n ):
81
+ for j in range (n ):
82
+ if (j , (n - 1 )- i ) in blocks :
83
+ grid [i ][j ] = "#"
84
+
85
+ grid [0 ][(n - 1 )] = "-"
86
+ x = back_pointer [goal ]
87
+ while x != start :
88
+ (x_c , y_c ) = x
89
+ # print(x)
90
+ grid [(n - 1 )- y_c ][x_c ] = "-"
91
+ x = back_pointer [x ]
92
+ grid [(n - 1 )][0 ] = "-"
93
+
94
+
95
+ for i in xrange (n ):
96
+ for j in range (n ):
97
+ if (i , j ) == (0 , n - 1 ):
98
+ print grid [i ][j ],
99
+ print "<-- End position" ,
100
+ else :
101
+ print grid [i ][j ],
102
+ print
103
+ print ("^" )
104
+ print ("Start position" )
105
+ print
106
+ print ("# is an obstacle" )
107
+ print ("- is the path taken by algorithm" )
108
+ print ("PATH TAKEN BY THE ALGORITHM IS:-" )
109
+ x = back_pointer [goal ]
110
+ while x != start :
111
+ print x ,
112
+ x = back_pointer [x ]
113
+ print x
114
+ quit ()
115
+
116
+ def valid (p ):
117
+ if p [0 ] < 0 or p [0 ] > n - 1 :
118
+ return False
119
+ if p [1 ] < 0 or p [1 ] > n - 1 :
120
+ return False
121
+ return True
122
+
123
+ def expand_state (s , j , visited , g_function , close_list_anchor , close_list_inad , open_list , back_pointer ):
124
+ for itera in range (n_hueristic ):
125
+ open_list [itera ].remove_element (s )
126
+ # print("s", s)
127
+ # print("j", j)
128
+ (x , y ) = s
129
+ left = (x - 1 , y )
130
+ right = (x + 1 , y )
131
+ up = (x , y + 1 )
132
+ down = (x , y - 1 )
133
+
134
+ for neighbours in [left , right , up , down ]:
135
+ if neighbours not in blocks :
136
+ if valid (neighbours ) and neighbours not in visited :
137
+ # print("neighbour", neighbours)
138
+ visited .add (neighbours )
139
+ back_pointer [neighbours ] = - 1
140
+ g_function [neighbours ] = float ('inf' )
141
+
142
+ if valid (neighbours ) and g_function [neighbours ] > g_function [s ] + 1 :
143
+ g_function [neighbours ] = g_function [s ] + 1
144
+ back_pointer [neighbours ] = s
145
+ if neighbours not in close_list_anchor :
146
+ open_list [0 ].put (neighbours , key (neighbours , 0 , goal , g_function ))
147
+ if neighbours not in close_list_inad :
148
+ for var in range (1 ,n_hueristic ):
149
+ if key (neighbours , var , goal , g_function ) <= W2 * key (neighbours , 0 , goal , g_function ):
150
+ # print("why not plssssssssss")
151
+ open_list [j ].put (neighbours , key (neighbours , var , goal , g_function ))
152
+
153
+
154
+ # print
155
+
156
+ def make_common_ground ():
157
+ some_list = []
158
+ # block 1
159
+ for x in range (1 , 5 ):
160
+ for y in range (1 , 6 ):
161
+ some_list .append ((x , y ))
162
+
163
+ # line
164
+ for x in range (15 , 20 ):
165
+ some_list .append ((x , 17 ))
166
+
167
+ # block 2 big
168
+ for x in range (10 , 19 ):
169
+ for y in range (1 , 15 ):
170
+ some_list .append ((x , y ))
171
+
172
+ # L block
173
+ for x in range (1 , 4 ):
174
+ for y in range (12 , 19 ):
175
+ some_list .append ((x , y ))
176
+ for x in range (3 , 13 ):
177
+ for y in range (16 , 19 ):
178
+ some_list .append ((x , y ))
179
+ return some_list
180
+
181
+ hueristics = {0 : consistent_hueristic , 1 : hueristic_1 , 2 : hueristic_2 }
182
+
183
+ blocks_blk = [(0 , 1 ),(1 , 1 ),(2 , 1 ),(3 , 1 ),(4 , 1 ),(5 , 1 ),(6 , 1 ),(7 , 1 ),(8 , 1 ),(9 , 1 ),(10 , 1 ),(11 , 1 ),(12 , 1 ),(13 , 1 ),(14 , 1 ),(15 , 1 ),(16 , 1 ),(17 , 1 ),(18 , 1 ), (19 , 1 )]
184
+ blocks_no = []
185
+ blocks_all = make_common_ground ()
186
+
187
+
188
+
189
+
190
+ blocks = blocks_blk
191
+ # hyper parameters
192
+ W1 = 1
193
+ W2 = 1
194
+ n = 20
195
+ n_hueristic = 3 # one consistent and two other inconsistent
196
+
197
+ # start and end destination
198
+ start = (0 , 0 )
199
+ goal = (n - 1 , n - 1 )
200
+
201
+ t = 1
202
+ def multi_a_star (start , goal , n_hueristic ):
203
+ g_function = {start : 0 , goal : float ('inf' )}
204
+ back_pointer = {start :- 1 , goal :- 1 }
205
+ open_list = []
206
+ visited = set ()
207
+
208
+ for i in range (n_hueristic ):
209
+ open_list .append (PriorityQueue ())
210
+ open_list [i ].put (start , key (start , i , goal , g_function ))
211
+
212
+ close_list_anchor = []
213
+ close_list_inad = []
214
+ while open_list [0 ].minkey () < float ('inf' ):
215
+ for i in range (1 , n_hueristic ):
216
+ # print("i", i)
217
+ # print(open_list[0].minkey(), open_list[i].minkey())
218
+ if open_list [i ].minkey () <= W2 * open_list [0 ].minkey ():
219
+ global t
220
+ t += 1
221
+ # print("less prio")
222
+ if g_function [goal ] <= open_list [i ].minkey ():
223
+ if g_function [goal ] < float ('inf' ):
224
+ do_something (back_pointer , goal , start )
225
+ else :
226
+ _ , get_s = open_list [i ].top_show ()
227
+ visited .add (get_s )
228
+ expand_state (get_s , i , visited , g_function , close_list_anchor , close_list_inad , open_list , back_pointer )
229
+ close_list_inad .append (get_s )
230
+ else :
231
+ # print("more prio")
232
+ if g_function [goal ] <= open_list [0 ].minkey ():
233
+ if g_function [goal ] < float ('inf' ):
234
+ do_something (back_pointer , goal , start )
235
+ else :
236
+ # print("hoolla")
237
+ get_s = open_list [0 ].top_show ()
238
+ visited .add (get_s )
239
+ expand_state (get_s , 0 , visited , g_function , close_list_anchor , close_list_inad , open_list , back_pointer )
240
+ close_list_anchor .append (get_s )
241
+ print ("No path found to goal" )
242
+ print
243
+ for i in range (n - 1 ,- 1 , - 1 ):
244
+ for j in range (n ):
245
+ if (j , i ) in blocks :
246
+ print '#' ,
247
+ elif (j , i ) in back_pointer :
248
+ if (j , i ) == (n - 1 , n - 1 ):
249
+ print '*' ,
250
+ else :
251
+ print '-' ,
252
+ else :
253
+ print '*' ,
254
+ if (j , i ) == (n - 1 , n - 1 ):
255
+ print '<-- End position' ,
256
+ print
257
+ print ("^" )
258
+ print ("Start position" )
259
+ print
260
+ print ("# is an obstacle" )
261
+ print ("- is the path taken by algorithm" )
262
+ multi_a_star (start , goal , n_hueristic )
0 commit comments