Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 683e767

Browse files
committed
Add Astar implementation
1 parent 0a5a145 commit 683e767

File tree

2 files changed

+115
-1
lines changed

2 files changed

+115
-1
lines changed

‎README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
- `bfs.py`
3030
- 04_dijkstra
3131
- `dijkstra.py`
32-
- a*
32+
- 05_astar
33+
-astar.py
3334
- mst_boruvka
3435
- mst_kruskal
3536
- mst_prim
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
from collections import deque
2+
3+
class Graph:
4+
# example of adjacency list (or rather map)
5+
# adjacency_list = {
6+
# 'A': [('B', 1), ('C', 3), ('D', 7)],
7+
# 'B': [('D', 5)],
8+
# 'C': [('D', 12)]
9+
# }
10+
11+
def __init__(self, adjacency_list):
12+
self.adjacency_list = adjacency_list
13+
14+
def get_neighbors(self, v):
15+
return self.adjacency_list[v]
16+
17+
# heuristic function with equal values for all nodes
18+
def h(self, n):
19+
H = {
20+
'A': 1,
21+
'B': 1,
22+
'C': 1,
23+
'D': 1
24+
}
25+
26+
return H[n]
27+
28+
def a_star_algorithm(self, start_node, stop_node):
29+
# open_list is a list of nodes which have been visited, but who's neighbors
30+
# haven't all been inspected, starts off with the start node
31+
# closed_list is a list of nodes which have been visited
32+
# and who's neighbors have been inspected
33+
open_list = set([start_node])
34+
closed_list = set([])
35+
36+
# g contains current distances from start_node to all other nodes
37+
# the default value (if it's not found in the map) is +infinity
38+
g = {}
39+
40+
g[start_node] = 0
41+
42+
# parents contains an adjacency map of all nodes
43+
parents = {}
44+
parents[start_node] = start_node
45+
46+
while len(open_list) > 0:
47+
n = None
48+
49+
# find a node with the lowest value of f() - evaluation function
50+
for v in open_list:
51+
if n == None or g[v] + self.h(v) < g[n] + self.h(n):
52+
n = v;
53+
54+
if n == None:
55+
print('Path does not exist!')
56+
return None
57+
58+
# if the current node is the stop_node
59+
# then we begin reconstructin the path from it to the start_node
60+
if n == stop_node:
61+
reconst_path = []
62+
63+
while parents[n] != n:
64+
reconst_path.append(n)
65+
n = parents[n]
66+
67+
reconst_path.append(start_node)
68+
69+
reconst_path.reverse()
70+
71+
print('Path found: {}'.format(reconst_path))
72+
return reconst_path
73+
74+
# for all neighbors of the current node do
75+
for (m, weight) in self.get_neighbors(n):
76+
# if the current node isn't in both open_list and closed_list
77+
# add it to open_list and note n as it's parent
78+
if m not in open_list and m not in closed_list:
79+
open_list.add(m)
80+
parents[m] = n
81+
g[m] = g[n] + weight
82+
83+
# otherwise, check if it's quicker to first visit n, then m
84+
# and if it is, update parent data and g data
85+
# and if the node was in the closed_list, move it to open_list
86+
else:
87+
if g[m] > g[n] + weight:
88+
g[m] = g[n] + weight
89+
parents[m] = n
90+
91+
if m in closed_list:
92+
closed_list.remove(m)
93+
open_list.add(m)
94+
95+
# remove n from the open_list, and add it to closed_list
96+
# because all of his neighbors were inspected
97+
open_list.remove(n)
98+
closed_list.add(n)
99+
100+
print('Path does not exist!')
101+
return None
102+
103+
def main():
104+
adjacency_list = {
105+
'A': [('B', 1), ('C', 3), ('D', 7)],
106+
'B': [('D', 5)],
107+
'C': [('D', 12)]
108+
}
109+
graph1 = Graph(adjacency_list)
110+
graph1.a_star_algorithm('A', 'D')
111+
112+
if __name__=="__main__":
113+
main()

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /