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
def shortest_path( graph: dsa.graph.AdjacencyListWeightedGraph, start: str, end: str, debug: bool = False) -> tuple:
 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.

def find_path1( graph: dsa.graph.AdjacencyListWeightedGraph, start: str, end: str, debug: bool = False) -> list:
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.

def find_path( graph: dsa.graph.AdjacencyListWeightedGraph, start: str, end: str, debug: bool = False) -> list:
 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.