[英]Python Implementation for Dijkstra's Algorithm doesn't work with all graph types
下面是我為實現編寫的代碼,它與在 function 之前初始化的名為“graph”的圖完美配合。 但它不斷遇到“graph2”錯誤。
'''
The graphs below will be used to test the directed and
undirected capabilities of my algorithm.
'''
graph = {"A": {"B": 2, "C" : 4},
"B" : {"C" : 5, "D" : 6},
"C" : {"D" : 2}
}
graph2 = {"A" : {"B" : 4, "C" : 2, "D" : 8},
"B" : {"A" : 4, "C" : 1, "D" : 3},
"C" : {"A" : 2, "B" : 1, "D" : 4},
"D" : {"A" : 8, "B" : 3, "C" : 4}
}
infinity = float("inf")
start = "A"
end = "D"
def DijkstrasAlgorithm(grid, sourceNode, endNode):
# "allnodes" is used to contain all nodes present in the grid inputted into the function.
# "visitedNodes" is used to store nodes that have been visited.
# "distances" stores edges (connections between 2 nodes) and their weights (the magnitude of their distance).
# "parents" is a dictionary used to form the basis with which the shortest path can be outputted, by interlinking the
# the parents of each class from the start to the end.
currentNode, allNodes, visitedNodes = sourceNode, set(), set()
distances, parents, paths = [], dict(), []
# This for loop adds all individual nodes to the set, which becomes a list, called 'allNodes'
for i in grid:
allNodes.add(i)
for j in grid[i]:
allNodes.add(j)
allNodes = sorted(list(allNodes))
#This for loop sets all distances between all nodes equal to infinity
for i in grid:
for j in grid[i]:
distances.append([i, j, infinity])
#This for loop sets the initial parent node of all nodes equal to None
for node in allNodes:
parents[node] = None
# This for loops sets the distances for all nodes that can be set
for i in grid:
for j in grid[i]:
try:
distances.append([i, j, grid[i][j]])
distances.remove([i, j, infinity])
except KeyError:
continue
except:
print("Error occurred during edge weight update.")
# This while loop is the actual part of the code that accounts for Dijkstras algorithm
# it continues to iterate choosing the node of minimum distance until the length of the 'allNodes' set is equal to zero
while len(allNodes) > 0:
# This if-statement ends the loop once the destination has been reached
if currentNode == endNode:
break
# These 2 statements remove the current node from the 'allNodes' set and add them to
# the visited nodes set
allNodes.remove(currentNode)
visitedNodes.add(currentNode)
comparisonRange = []
# This for loop chooses the closes nodes to the comparison node to compare
# and select the node of minimum distance
for edge in distances:
if (edge[0] == currentNode) and (edge[1] not in visitedNodes):
comparisonRange.append(edge)
comparisonRange = sorted(comparisonRange, key = lambda x: x[2])
parents[comparisonRange[0][1]] = currentNode
currentNode = comparisonRange[0][1]
# The above code is the 'greedy' part of the algorithm selecting the node of minimum distance
# each time
possiblePath = []
# The for loop below appends the nodes in order of visitation
# Its starts with the node whose parent is still None, which can only be the start node
# and all nodes that branch from it and so on so forth are appended to the possiblePath list.
# This ensures possible path holds the nodes in order of visitation.
for node in parents.keys():
if parents[node] == None:
possiblePath.append(node)
if parents[node] in possiblePath:
possiblePath.append(node)
# This code adds one possible path to the group of possible paths named 'paths'
paths.append(possiblePath)
# This for loop creates other possible paths spanning from the first one
# simply by deleting a previous choice
for i in range(len(paths[0]) - 1):
alternatePath = [element for element in paths[i]]
alternatePath.pop(1)
if len(alternatePath) == 2:
break
paths.append(alternatePath)
# This list holds zero for the initial length of each possible path
pathLengths =[[0] for item in paths]
# This for loop is used to calculate the lengths of possible paths from
# items contained within each possible path. This is done by passing those
# items into the 'graph' dictionary and calculating the length between them
for path in paths:
length = 0
for index in path:
try:
for secondKey in grid[index]:
if secondKey == path[path.index(index)+1]:
try:
length += grid[index][secondKey]
except KeyError:
continue
pathLengths[paths.index(path)] = length
except KeyError:
continue
# The minimum path variable below chooses the minimum length in pathLengths
# and uses that index to find the path that it corresponds to in the list
# paths
minimumPath = paths[pathLengths.index(min(pathLengths))]
return minimumPath
DijkstrasAlgorithm(graph, start, end)
我也考慮過使用類,但我不知道如何實現它們。
請告訴我你的想法,給我關於如何改進代碼和我的編程技能的建議,你能否告訴我我可以使用的任何方法,以確保我的實現可以在輸入到其中的任何圖形上工作。
If you can use the adjacency matrix ( https://en.wikipedia.org/wiki/Adjacency_matrix ) in graph algorithms because it is faster, like in https://gist.github.com/shintoishere/f0fa40fe1134b20e7729
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.