Skip to content

Commit aa15ab8

Browse files
authored
Merge pull request TheAlgorithms#197 from yashasvi97/yashasvi97-MHAstar
Added Multi Heuristic Astar
2 parents 4945623 + 8cd5157 commit aa15ab8

File tree

1 file changed

+262
-0
lines changed

1 file changed

+262
-0
lines changed

Multi_Hueristic_Astar.py

+262
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
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

Comments
 (0)