dsa.dijkstras
Module to access functions for Dijkstra's Algorithm.
1""" Module to access functions for Dijkstra's Algorithm. """ 2from dsa.heap import MinHeap 3from dsa.graph import AdjacencyListWeightedGraph 4 5def shortest_path(graph: AdjacencyListWeightedGraph, start: str, end: str, debug: bool=False) -> tuple: 6 """ 7 Helper function that returns a weight table and a predecessor table using Dijkstra's Algorithm. 8 9 Args: 10 graph (AdjacencyListWeighted Graph): The graph to search. 11 start (str): The starting vertex label. 12 end (str): The ending vertex label. 13 debug (bool): If True, display weight table as it is being built. 14 15 Raises: 16 KeyError: If start or end vertex is not in the graph. 17 18 Returns: 19 A tuple of a weight table hashtable and a predecessor predecessorhashtable. 20 """ 21 if start not in graph: 22 raise KeyError(f"Start vertex {start} not in graph.") 23 if end not in graph: 24 raise KeyError(f"End vertex {end} not in graph.") 25 26 weight_table = {start: 0} 27 predecessor = {start: start} 28 visited = set() 29 pq = MinHeap() 30 31 pq.insert((0, start)) 32 33 while not pq.is_empty(): 34 current_weight, current = pq.pop() 35 if current in visited: 36 continue 37 visited.add(current) 38 39 if current == end: 40 break 41 42 for adjacent, weight in graph[current].items(): 43 new_dist = current_weight + weight 44 if new_dist < weight_table.get(adjacent, float('inf')): 45 weight_table[adjacent] = new_dist 46 predecessor[adjacent] = current 47 pq.insert((new_dist, adjacent)) 48 if debug: 49 print(weight_table) 50 51 return weight_table, predecessor 52 53def find_path1(graph: AdjacencyListWeightedGraph, start: str, end: str, debug: bool=False) -> list: 54 """ 55 Return the shortest path of two vertices using Dijkstra's Algorithm. 56 57 Args: 58 graph (AdjacencyListWeighted Graph): The graph to search. 59 start (str): The starting vertex label. 60 end (str): The ending vertex label. 61 debug (bool): If True, display the weight table. 62 63 Returns: 64 A list of vertices that form a shortest path. 65 """ 66 weight_table, predecessor = shortest_path(graph, start, end, debug) 67 path = [] 68 69 current = end 70 path.append(current) 71 while current != start: 72 current = predecessor[current] 73 path.append(current) 74 75 path.reverse() 76 77 if debug: 78 print("predecessor table") 79 print(predecessor) 80 81 print("weight table") 82 print(weight_table) 83 print("shortest path weight ", weight_table[end]) 84 return path 85 86 87def find_path(graph: AdjacencyListWeightedGraph, start: str, end: str, debug: bool=False) -> list: 88 """ 89 Return the shortest path of two vertices using Dijkstra's Algorithm. 90 91 Args: 92 graph (AdjacencyListWeighted Graph): The graph to search. 93 start (str): The starting vertex label. 94 end (str): The ending vertex label. 95 debug (bool): If True, display the weight table. 96 97 Raises: 98 KeyError: If there is no path from start to end. 99 100 Returns: 101 A list of vertices that form a shortest path. 102 """ 103 weight_table, predecessor = shortest_path(graph, start, end, debug) 104 105 # No path or invalid start/end 106 if end not in predecessor: 107 raise KeyError(f"No path from {start} to {end}.") 108 109 path = [] 110 current = end 111 path.append(current) 112 113 while current != start: 114 current = predecessor[current] 115 path.append(current) 116 117 path.reverse() 118 119 if debug: 120 print("predecessor table") 121 print(predecessor) 122 print("weight table") 123 print(weight_table) 124 print("shortest path weight", weight_table[end]) 125 126 return path
6def shortest_path(graph: AdjacencyListWeightedGraph, start: str, end: str, debug: bool=False) -> tuple: 7 """ 8 Helper function that returns a weight table and a predecessor table using Dijkstra's Algorithm. 9 10 Args: 11 graph (AdjacencyListWeighted Graph): The graph to search. 12 start (str): The starting vertex label. 13 end (str): The ending vertex label. 14 debug (bool): If True, display weight table as it is being built. 15 16 Raises: 17 KeyError: If start or end vertex is not in the graph. 18 19 Returns: 20 A tuple of a weight table hashtable and a predecessor predecessorhashtable. 21 """ 22 if start not in graph: 23 raise KeyError(f"Start vertex {start} not in graph.") 24 if end not in graph: 25 raise KeyError(f"End vertex {end} not in graph.") 26 27 weight_table = {start: 0} 28 predecessor = {start: start} 29 visited = set() 30 pq = MinHeap() 31 32 pq.insert((0, start)) 33 34 while not pq.is_empty(): 35 current_weight, current = pq.pop() 36 if current in visited: 37 continue 38 visited.add(current) 39 40 if current == end: 41 break 42 43 for adjacent, weight in graph[current].items(): 44 new_dist = current_weight + weight 45 if new_dist < weight_table.get(adjacent, float('inf')): 46 weight_table[adjacent] = new_dist 47 predecessor[adjacent] = current 48 pq.insert((new_dist, adjacent)) 49 if debug: 50 print(weight_table) 51 52 return weight_table, predecessor
Helper function that returns a weight table and a predecessor table using Dijkstra's Algorithm.
Args: graph (AdjacencyListWeighted Graph): The graph to search. start (str): The starting vertex label. end (str): The ending vertex label. debug (bool): If True, display weight table as it is being built.
Raises: KeyError: If start or end vertex is not in the graph.
Returns: A tuple of a weight table hashtable and a predecessor predecessorhashtable.
54def find_path1(graph: AdjacencyListWeightedGraph, start: str, end: str, debug: bool=False) -> list: 55 """ 56 Return the shortest path of two vertices using Dijkstra's Algorithm. 57 58 Args: 59 graph (AdjacencyListWeighted Graph): The graph to search. 60 start (str): The starting vertex label. 61 end (str): The ending vertex label. 62 debug (bool): If True, display the weight table. 63 64 Returns: 65 A list of vertices that form a shortest path. 66 """ 67 weight_table, predecessor = shortest_path(graph, start, end, debug) 68 path = [] 69 70 current = end 71 path.append(current) 72 while current != start: 73 current = predecessor[current] 74 path.append(current) 75 76 path.reverse() 77 78 if debug: 79 print("predecessor table") 80 print(predecessor) 81 82 print("weight table") 83 print(weight_table) 84 print("shortest path weight ", weight_table[end]) 85 return path
Return the shortest path of two vertices using Dijkstra's Algorithm.
Args: graph (AdjacencyListWeighted Graph): The graph to search. start (str): The starting vertex label. end (str): The ending vertex label. debug (bool): If True, display the weight table.
Returns: A list of vertices that form a shortest path.
88def find_path(graph: AdjacencyListWeightedGraph, start: str, end: str, debug: bool=False) -> list: 89 """ 90 Return the shortest path of two vertices using Dijkstra's Algorithm. 91 92 Args: 93 graph (AdjacencyListWeighted Graph): The graph to search. 94 start (str): The starting vertex label. 95 end (str): The ending vertex label. 96 debug (bool): If True, display the weight table. 97 98 Raises: 99 KeyError: If there is no path from start to end. 100 101 Returns: 102 A list of vertices that form a shortest path. 103 """ 104 weight_table, predecessor = shortest_path(graph, start, end, debug) 105 106 # No path or invalid start/end 107 if end not in predecessor: 108 raise KeyError(f"No path from {start} to {end}.") 109 110 path = [] 111 current = end 112 path.append(current) 113 114 while current != start: 115 current = predecessor[current] 116 path.append(current) 117 118 path.reverse() 119 120 if debug: 121 print("predecessor table") 122 print(predecessor) 123 print("weight table") 124 print(weight_table) 125 print("shortest path weight", weight_table[end]) 126 127 return path
Return the shortest path of two vertices using Dijkstra's Algorithm.
Args: graph (AdjacencyListWeighted Graph): The graph to search. start (str): The starting vertex label. end (str): The ending vertex label. debug (bool): If True, display the weight table.
Raises: KeyError: If there is no path from start to end.
Returns: A list of vertices that form a shortest path.