Skip to content

Commit f20d1b0

Browse files
committed
Breadth-first search
1 parent 2d6bd85 commit f20d1b0

File tree

2 files changed

+77
-1
lines changed

2 files changed

+77
-1
lines changed

breadth_first_search.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
""" Breadth-first search
2+
3+
This ignores the distance between the city data, and just cares about number of hops.
4+
5+
This implementation is admittedly tightly-coupled to my particular city_data data set
6+
(to add clarity in understanding by making it tied to concrete data).
7+
8+
The city_data is a list of 28 large cities in the United States, with some considered
9+
neighbors of the others. This would be the case in, say, a bus system which only
10+
travels between major cities. Using the shortest path on this data outputs
11+
the best path through these major cities.
12+
13+
The format of city_data is like this:
14+
15+
{ "Milwaukee, WI": {"Minneapolis, MN": 542093, "Chicago, IL": 148198},
16+
"Minneapolis, MN": {"Seattle, WA": 2665735, "Milwaukee, WI": 541660}, ... }
17+
18+
So the neighbors of a city node can be found like this: list(city_data["Milwaukee, WI"].keys())
19+
20+
"""
21+
22+
import json
23+
import sys
24+
from collections import deque
25+
26+
27+
def unroll_shortest_path(current, optimal_parent_map, path=()):
28+
if current is None: # Reached the start node
29+
return path
30+
else:
31+
return unroll_shortest_path(optimal_parent_map[current], optimal_parent_map, (current,) + path)
32+
33+
34+
def breadth_first_search(from_city, to_city, city_data):
35+
to_visit = deque([from_city])
36+
visited = set([from_city])
37+
parent_map = {from_city: None}
38+
39+
while to_visit != []:
40+
current = to_visit.popleft() # Treat to_visit as queue
41+
visited.add(current)
42+
neighbors = city_data[current].keys()
43+
44+
for n in neighbors:
45+
if n == to_city:
46+
parent_map[n] = current
47+
return unroll_shortest_path(to_city, parent_map)
48+
49+
elif n not in visited:
50+
parent_map[n] = current
51+
to_visit.append(n)
52+
53+
return None
54+
55+
56+
def get_city_data():
57+
city_data = None
58+
with open("city_data.json","r") as f:
59+
city_data = json.loads(f.read())
60+
return city_data
61+
62+
63+
if __name__ == '__main__':
64+
city_data = get_city_data()
65+
try:
66+
city_from = sys.argv[1]
67+
city_to = sys.argv[2]
68+
except IndexError:
69+
print("Usage:", sys.argv[0], "\"from city\" \"to city>\"")
70+
print("City choices:")
71+
for city in city_data:
72+
print(" -", city)
73+
sys.exit(1)
74+
75+
print(breadth_first_search(city_from, city_to, city_data))
76+

depth_first_search.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
""" Breadth-first search
1+
""" Depth-first search (recursive and iterative solutions)
22
33
This ignores the distance between the city data, and just cares about number of hops.
44

0 commit comments

Comments
 (0)