Skip to content
Open
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
51 changes: 32 additions & 19 deletions graphs/dijkstra.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,33 +31,30 @@
vertex.
"""
import heapq
from typing import Dict
from typing import List, Tuple, Dict
from typing import List, Tuple, Dict


def dijkstra(graph, start, end):
"""Return the cost of the shortest path between vertices start and end.

>>> dijkstra(G, "E", "C")
6
>>> dijkstra(G2, "E", "F")
3
>>> dijkstra(G3, "E", "F")
3
def dijkstra(graph: Dict[str, List[Tuple[str, int]]], start: str, end: str) -> int:
"""

heap = [(0, start)] # cost from start node,end node
In the given graph, it finds the shortest path from start to end and returns it's cost. If the end is not reachable from start it returns -1.
"""
heap = [(0, start)] # cost from start node, end node
visited = set()

while heap:
(cost, u) = heapq.heappop(heap)
if u in visited:
(cost, current_node) = heapq.heappop(heap)
if current_node in visited:
continue
visited.add(u)
if u == end:

visited.add(current_node)
if current_node == end:
return cost
for v, c in graph[u]:
if v in visited:
continue
next_item = cost + c
heapq.heappush(heap, (next_item, v))

push_to_heap_unvisited_neighbors(graph, heap, visited, cost, current_node)

return -1


Expand All @@ -70,6 +67,22 @@ def dijkstra(graph, start, end):
"F": [["C", 3], ["E", 3]],
}


def push_to_heap_unvisited_neighbors(
graph: Dict[str, List[Tuple[str, int]]],
heap: List[Tuple[int, str]],
visited: set,
cost: int,
current_node: str,
):
"""
Helper function for dijkstra(). It pushes unvisited neighbors of current_node into the heap.
"""
for neighbor, cost_to_travel in graph[current_node]:
if neighbor not in visited:
total_cost = cost + cost_to_travel
heapq.heappush(heap, (total_cost, neighbor))

r"""
Layout of G2:

Expand Down
50 changes: 50 additions & 0 deletions tests/refactory/test_dijkstra_dijkstra.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from graphs.dijkstra import *
import pytest


def test_dijkstra_successful_execution():
graph = {
"A": [("B", 1), ("C", 3)],
"B": [("A", 1), ("C", 2)],
"C": [("A", 3), ("B", 2)],
}
start = "A"
end = "C"

result = dijkstra(graph, start, end)
assert result is not None


def test_dijkstra_negative_path():
graph = {
"A": [("B", 1)],
"B": [("A", 1)],
"C": [],
}
start = "A"
end = "C"

result = dijkstra(graph, start, end)
assert result == -1


def test_dijkstra_same_start_and_end():
graph = {
"A": [("B", 1), ("C", 3)],
"B": [("A", 1), ("C", 2)],
"C": [("A", 3), ("B", 2)],
}
start = "A"
end = "A"

result = dijkstra(graph, start, end)
assert result == 0


def test_dijkstra_no_path_but_nodes_exist():
graph = {"A": [("B", 1)], "B": [("A", 1)], "C": [("D", 2)], "D": [("C", 2)]}
start = "A"
end = "C"

result = dijkstra(graph, start, end)
assert result == -1