I have implemented a minimum cost path function to my undirected weighted graph using an adjacency list. My approach of the minimum cost path function does not use a priority queue. My goal is to calculate and display the shortest path from a starting node.
I'm able to calculate the shortest path starting at node A, however, the order of the nodes does not match the order of the nodes. Would it be better if I implemented a priority queue? Any help would be appreciated!
The minimum cost paths starting at A
Expected B(4) C(12) D(19) E(21) F(11) G(9) H(8) I(14) J(inf)
Actually B(4) H(8) C(12) G(9) I(14) D(19) F(11) E(21)
The adjacency list:
A- {'B': 4, 'H': 8}
B- {'A': 4, 'C': 8, 'H': 11}
C- {'B': 8, 'D': 7, 'F': 4, 'I': 2}
D- {'C': 7, 'E': 9, 'F': 14}
E- {'D': 9, 'F': 10}
F- {'C': 4, 'D': 14, 'E': 10, 'G': 2}
G- {'F': 2, 'H': 1, 'I': 6}
H- {'A': 8, 'B': 11, 'G': 1, 'I': 7}
I- {'C': 2, 'G': 6, 'H': 7}
J- {}
My code
class WGraph:
def __init__(self, size=10):
self.size = 10
self.nodeList = {}
self.adjacencyMatrix = [[0] * size for i in range(size)] # initialize matrix
def addNode(self, name):
"""Adds node to adjacency list"""
self.nodeList[name] = {}
def addEdge(self, startIndex, endIndex, weight):
"""Add edges for adjacency list and matrix"""
self.nodeList[startIndex][endIndex] = weight
self.nodeList[endIndex][startIndex] = weight
index1 = list(self.nodeList.keys()).index(startIndex)
index2 = list(self.nodeList.keys()).index(endIndex)
self.adjacencyMatrix[index1][index2] = weight
def displayAdjacency(self):
"""Displays adjacency list with edges and weight"""
for node in self.nodeList:
print(node "- " str(self.nodeList[node]))
def minCostPaths(self, vertex):
visited = {vertex: 0}
queue = [(vertex, 0)]
while queue:
node, cost = queue.pop(0)
for neighbor in self.nodeList[node]:
if neighbor not in visited or cost self.nodeList[node][neighbor] < visited[neighbor]:
visited[neighbor] = cost self.nodeList[node][neighbor]
queue.append((neighbor, cost self.nodeList[node][neighbor]))
output = ""
for node in visited:
if node != vertex:
output = f"{node}({visited[node]}) "
return output[:-2] ")"
# Driver Code
graph = WGraph()
graph.addNode('A')
graph.addNode('B')
graph.addNode('C')
graph.addNode('D')
graph.addNode('E')
graph.addNode('F')
graph.addNode('G')
graph.addNode('H')
graph.addNode('I')
graph.addNode('J')
graph.addEdge('A', 'B', 4)
graph.addEdge('A', 'H', 8)
graph.addEdge('B', 'C', 8)
graph.addEdge('B', 'H', 11)
graph.addEdge('C', 'D', 7)
graph.addEdge('C', 'F', 4)
graph.addEdge('C', 'I', 2)
graph.addEdge('D', 'E', 9)
graph.addEdge('D', 'F', 14)
graph.addEdge('E', 'F', 10)
graph.addEdge('F', 'G', 2)
graph.addEdge('G', 'H', 1)
graph.addEdge('G', 'I', 6)
graph.addEdge('H', 'I', 7)
graph.displayAdjacency()
print("The minimum cost paths starting at A ")
print(" Expected B(4) C(12) D(19) E(21) F(11) G(9) H(8) I(14) J(inf) ")
print(" Actually " graph.minCostPaths('A'), end="\n")
CodePudding user response:
In your minCostPaths()
function, you need to get the list of vertices from self.nodeList
, not from visited
. The order of BFS traversal is stored in visited
, which isn't the ordering you need.
output = ""
for node in self.nodeList:
if node != vertex:
output = f"{node}({visited.get(node, 'inf')}) "
return output[:-2] ")"
Output:
The minimum cost paths starting at A
Expected B(4) C(12) D(19) E(21) F(11) G(9) H(8) I(14) J(inf)
Actually B(4) C(12) D(19) E(21) F(11) G(9) H(8) I(14) J(inf)