Skip to content

Implement Dijkstra's Algorithm for Shortest Path #89

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions graph/dijkstra.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from typing import Dict, List, Tuple
import heapq

def dijkstra(graph: Dict[int, List[Tuple[int, int]]], start: int) -> Dict[int, int]:
"""
Implements Dijkstra's algorithm for finding the shortest path in a graph.

Args:
graph (Dict[int, List[Tuple[int, int]]]): A dictionary representing the graph.
Keys are nodes, values are lists of (neighbor, weight) tuples.
start (int): The starting node.

Returns:
Dict[int, int]: A dictionary with nodes as keys and shortest distances from start as values.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add some more comments under this line

"""
distances = {node: float('infinity') for node in graph}
distances[start] = 0
pq = [(0, start)]

while pq:
current_distance, current_node = heapq.heappop(pq)

if current_distance > distances[current_node]:
continue

for neighbor, weight in graph[current_node]:
distance = current_distance + weight
if distance < distances[neighbor]:
distances[neighbor] = distance
heapq.heappush(pq, (distance, neighbor))

return distances

# Example usage
if __name__ == "__main__":
# Simple graph example
simple_graph = {
0: [(1, 4), (2, 1)],
1: [(3, 1)],
2: [(1, 2), (3, 5)],
3: [(4, 3)],
4: []
}

print("Simple Graph Example:")
start_node = 0
shortest_paths = dijkstra(simple_graph, start_node)
print(f"Shortest paths from node {start_node}:")
for node, distance in shortest_paths.items():
print(f"To node {node}: {distance}")

# More complex graph example
complex_graph = {
0: [(1, 4), (2, 2)],
1: [(2, 1), (3, 5)],
2: [(3, 8), (4, 10)],
3: [(4, 2), (5, 6)],
4: [(5, 3)],
5: [(6, 1)],
6: [(4, 4), (7, 2)],
7: []
}
Comment on lines +53 to +62
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add an even more complex graph


print("\nComplex Graph Example:")
start_node = 0
shortest_paths = dijkstra(complex_graph, start_node)
print(f"Shortest paths from node {start_node}:")
for node, distance in shortest_paths.items():
print(f"To node {node}: {distance}")
54 changes: 54 additions & 0 deletions graph/test_dijkstra.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import unittest
from dijkstra import dijkstra

class TestDijkstra(unittest.TestCase):
def test_simple_graph(self):
graph = {
0: [(1, 4), (2, 1)],
1: [(3, 1)],
2: [(1, 2), (3, 5)],
3: [(4, 3)],
4: []
}
start_node = 0
expected = {0: 0, 1: 3, 2: 1, 3: 4, 4: 7}
self.assertEqual(dijkstra(graph, start_node), expected)

def test_disconnected_graph(self):
graph = {
0: [(1, 1)],
1: [(0, 1)],
2: [(3, 1)],
3: [(2, 1)]
}
start_node = 0
expected = {0: 0, 1: 1, 2: float('infinity'), 3: float('infinity')}
self.assertEqual(dijkstra(graph, start_node), expected)

def test_single_node_graph(self):
graph = {0: []}
start_node = 0
expected = {0: 0}
self.assertEqual(dijkstra(graph, start_node), expected)

def test_complex_graph(self):
graph = {
0: [(1, 4), (2, 2)],
1: [(2, 1), (3, 5)],
2: [(3, 8), (4, 10)],
3: [(4, 2), (5, 6)],
4: [(5, 3)],
5: []
}
start_node = 0
expected = {0: 0, 1: 4, 2: 2, 3: 9, 4: 11, 5: 14}
self.assertEqual(dijkstra(graph, start_node), expected)

def test_start_node_not_in_graph(self):
graph = {0: [(1, 1)], 1: [(0, 1)]}
start_node = 2
with self.assertRaises(KeyError):
dijkstra(graph, start_node)

if __name__ == '__main__':
unittest.main()
Loading