dijkstra’s algorithm implemented with a min-heap

11
Dijkstra’s Algorithm Implemented with a Min-Heap https://courses.missouristate.edu/anthonyclark/325

Upload: others

Post on 07-Apr-2022

13 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Dijkstra’s Algorithm Implemented with a Min-Heap

Dijkstra’s Algorithm Implemented with a Min-Heap

https://courses.missouristate.edu/anthonyclark/325

Page 2: Dijkstra’s Algorithm Implemented with a Min-Heap

Outline

Topics and Learning Objectives• Look at Dijkstra’s Algorithm when implemented using a heap

Assessments• None

Page 3: Dijkstra’s Algorithm Implemented with a Min-Heap

def dijkstras_heap(adjacency_list, start_vertex):"""Dijkstra's Algorithm implemented with all vertices placed in a heap.

This version of Dijkstra's Algorithm has a running time of O(m lg n)."""

n = len(adjacency_list)

path_lengths = {v: inf for v in adjacency_list}predecessors = {v: None for v in adjacency_list}

path_lengths[start_vertex] = 0predecessors[start_vertex] = None

found = set()vertex_min_heap = [(path_lengths[start_vertex], start_vertex)]

while len(found) != n:vfrom_length, vfrom = heappop(vertex_min_heap)found.add(vfrom)

for vto, weight in adjacency_list[vfrom]:path_length = vfrom_length + weightif path_length < path_lengths[vto]:

path_lengths[vto] = path_lengthpredecessors[vto] = vfrom

heappush(vertex_min_heap, (path_lengths[vto], vto))

return path_lengths, predecessors

Page 4: Dijkstra’s Algorithm Implemented with a Min-Heap

while len(found) != n:vfrom_length, vfrom = heappop(vertex_min_heap)found.add(vfrom)

for vto, weight in adjacency_list[vfrom]:path_length = vfrom_length + weightif path_length < path_lengths[vto]:

path_lengths[vto] = path_lengthpredecessors[vto] = vfrom

heappush(vertex_min_heap, (path_lengths[vto], vto))

Page 5: Dijkstra’s Algorithm Implemented with a Min-Heap

def print_path(end_vertex, predecessors):

path = [end_vertex]pred = predecessors[end_vertex]

while pred is not None:

path.append(pred)pred = predecessors[pred]

print(" -> ".join([str(v) for v in reversed(path)]))

Page 6: Dijkstra’s Algorithm Implemented with a Min-Heap

Dijkstra’s Algorithm Correctness

Theorem:• Dijkstra’s algorithm will find the shortest path from the start vertex to

every other vertex on any graph with non-negative weights.

Proof using a loop invariant. Loop predicate:• At the start of each iteration of the while loop, the shortest path has

been found for every vertex in the found set

Page 7: Dijkstra’s Algorithm Implemented with a Min-Heap

Initialization

• Initially, the found set is empty. So, the invariant is trivially true.

Loop predicate/invariant: At the start of each iteration of the while loop, the shortest path has been found for every vertex in the found set

while len(found) != n:vfrom_length, vfrom = heappop(vertex_min_heap)found.add(vfrom)

for vto, weight in adjacency_list[vfrom]:path_length = vfrom_length + weightif path_length < path_lengths[vto]:

path_lengths[vto] = path_lengthpredecessors[vto] = vfrom

heappush(vertex_min_heap,(path_lengths[vto], vto))

Page 8: Dijkstra’s Algorithm Implemented with a Min-Heap

Maintenance (1)

• Assume all previous iterations have produced the correct shortest path for all vertices in the found set.• For purposes of a contradiction,

assume that when a vertex u is added to the found set its path length is not optimal.• At the time u is found we must

have some path to u

Loop predicate/invariant: At the start of each iteration of the while loop, the shortest path has been found for every vertex in the found set

while len(found) != n:vfrom_length, vfrom = heappop(vertex_min_heap)found.add(vfrom)

for vto, weight in adjacency_list[vfrom]:path_length = vfrom_length + weightif path_length < path_lengths[vto]:

path_lengths[vto] = path_lengthpredecessors[vto] = vfrom

heappush(vertex_min_heap,(path_lengths[vto], vto))

Page 9: Dijkstra’s Algorithm Implemented with a Min-Heap

Maintenance (1)

• Assume all previous iterations have produced the correct shortest path for all vertices in the found set.• For purposes of a contradiction,

assume that when a vertex u is added to the found set its path length is not optimal.• At the time u is found we must

have some path to u

Loop predicate/invariant: At the start of each iteration of the while loop, the shortest path has been found for every vertex in the found set

while len(found) != n:vfrom_length, vfrom = heappop(vertex_min_heap)found.add(vfrom)

for vto, weight in adjacency_list[vfrom]:path_length = vfrom_length + weightif path_length < path_lengths[vto]:

path_lengths[vto] = path_lengthpredecessors[vto] = vfrom

heappush(vertex_min_heap,(path_lengths[vto], vto))

Page 10: Dijkstra’s Algorithm Implemented with a Min-Heap

Maintenance (1)

• For purposes of a contradiction, assume that when a vertex u is added to the found set its path length is not optimal.• At the time u is found we must have

some path to u• To have a shorter path to u, it must

go through some vertex k not in found.• But a shorter path going through k,

means that k must have been chosen before u.

Loop predicate/invariant: At the start of each iteration of the while loop, the shortest path has been found for every vertex in the found set

while len(found) != n:vfrom_length, vfrom = heappop(vertex_min_heap)found.add(vfrom)

for vto, weight in adjacency_list[vfrom]:path_length = vfrom_length + weightif path_length < path_lengths[vto]:

path_lengths[vto] = path_lengthpredecessors[vto] = vfrom

heappush(vertex_min_heap,(path_lengths[vto], vto))

Page 11: Dijkstra’s Algorithm Implemented with a Min-Heap

Termination

• The loop terminates when all vertices have been added to the found set.• Given the loop invariant the

shortest path to all vertices have been calculated.

Loop predicate/invariant: At the start of each iteration of the while loop, the shortest path has been found for every vertex in the found set

while len(found) != n:vfrom_length, vfrom = heappop(vertex_min_heap)found.add(vfrom)

for vto, weight in adjacency_list[vfrom]:path_length = vfrom_length + weightif path_length < path_lengths[vto]:

path_lengths[vto] = path_lengthpredecessors[vto] = vfrom

heappush(vertex_min_heap,(path_lengths[vto], vto))