forked from CMAP-REPOS/mrn_programs
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfind_shortest_path.py
65 lines (58 loc) · 3.86 KB
/
find_shortest_path.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
###############################################################################
# FIND_SHORTEST_PATH.PY #
# Craig Heither, rev. 07-24-2012 #
# #
# This script finds the shortest path between two nodes, given the available #
# network. The source of the shortest path function is: #
# http://rebrained.com/?p=392 (accessed September 2011) - author unknown #
# #
# The function uses a brute force method to determine the shortest path: a #
# bit inelegant but effective. #
# #
# Revisions: #
# - 07-24-2012: updated for Python 3.2 (print now function, sys.maxint #
# replaced with sys.maxsize) #
# #
###############################################################################
# ---------------------------------------------------------------
# Import System Modules and Set Variables.
# ---------------------------------------------------------------
import sys, os, csv
input = os.path.join(sys.argv[3], "Import\\link_dictionary.txt") ## input file with distance dictionary
short = os.path.join(sys.argv[3], "Import\\short_path.txt") ## shortest path output file
sys.setrecursionlimit(6000) ## max. times function will call itself (default=1000)
##======================================================================##
# ---------------------------------------------------------------
#
# ---------------------------------------------------------------
graph={}
reader = csv.reader(open(input), delimiter='$')
for row in reader:
graph[eval(row[0])]=eval(row[1]) ### assigns key (first object in row [0]) & value (2nd object in row [1]) pair
### eval function converts from string to integers
## function written by unknown author to find shortest path between 2 nodes in a graph; implementation of Dijkstra's algorithm
def shortestpath(graph,start,end,visited=[],distances={},predecessors={}):
if not visited: distances[start]=0 # set distance to 0 for first pass
if start==end: # we've found our end node, now find the path to it, and return
path=[]
while end != None:
path.append(end)
end=predecessors.get(end,None)
return distances[start], path[::-1]
for neighbor in graph[start]: # process neighbors as per algorithm, keep track of predecessors
if neighbor not in visited:
neighbordist = distances.get(neighbor,sys.maxsize)
tentativedist = distances[start] + graph[start][neighbor]
if tentativedist < neighbordist:
distances[neighbor] = tentativedist
predecessors[neighbor]=start
visited.append(start) # mark the current node as visited
unvisiteds = dict((k, distances.get(k,sys.maxsize)) for k in graph if k not in visited) # finds the closest unvisited node to the start
closestnode = min(unvisiteds, key=unvisiteds.get)
return shortestpath(graph,closestnode,end,visited,distances,predecessors) # start processing the closest node
print(str(sys.argv[1]) + "," + str(sys.argv[2]))
outFile = open(short, 'a')
outFile.write(str(shortestpath(graph,eval(sys.argv[1]),eval(sys.argv[2]))))
outFile.write("\n")
outFile.close()
print('DONE')