Module dsa.graph
Functions
def find_path(start, end, debug=False)
-
Return the shortest path of two vertices using Dijkstra's Algorithm.
Args
start
- starting vertex
end
- ending vertex
debug
- if True, display the weight table
Returns: A list of vertices that form a shortest path
def shortest_path(start, end, debug=False)
-
Helper function that returns a weight table and a previous vertex table using Dijkstra's Algorithm.
Args
start
- starting vertex
end
- ending vertex
debug
- if True, display weight table as it is being built
Returns: a tuple of a weight table dictionary and a previous path dictionary
Classes
class AdjacencyMatrixGraph (labels: list[str])
-
An unweighted adjacency matrix graph implementation in Python (allows either directed or undirected representation)
Args
labels
- list of labels for each vertex
Expand source code
class AdjacencyMatrixGraph: """ An unweighted adjacency matrix graph implementation in Python (allows either directed or undirected representation) """ def __init__(self, labels: list[str]): """ Args: labels: list of labels for each vertex """ self.labels = labels self.label_index = { label: index for index, label in enumerate(labels) } node_count = len(self.labels) self.array = [[None for i in range(node_count)] for j in range(node_count)] def add_edge(self, a_label: str, b_label: str): """ Add an undirected edge between one vertex to another (same as add_edge()) Args: a_label: starting vertex label b_label: ending vertex label """ self.add_adjacent_vertex(a_label, b_label) def add_adjacent_vertex(self, a_label: str, b_label: str): """ Add an undirected edge between one vertex to another (same as add_adjacent_vertex()) Args: a_label: starting vertex label b_label: ending vertex label """ a = self.label_index[a_label] b = self.label_index[b_label] self.array[a][b] = True self.array[a][a] = True self.array[b][a] = True self.array[b][b] = True def add_directed_edge(self, a_label: str, b_label: str): """ Add a directed edge between one vertex to another (same as add_directed_adjacent_vertex() and add_adjacent_directed_vertex()) Args: a_label: starting vertex label b_label: ending vertex label """ self.add_adjacent_directed_vertex(a_label, b_label) def add_directed_adjacent_vertex(self, a_label: str, b_label: str): """ Add a directed edge between one vertex to another (same as add_adjacent_directed_vertex() and add_directed_edge()) Args: a_label: starting vertex label b_label: ending vertex label """ self.add_adjacent_directed_vertex(a_label, b_label) def add_adjacent_directed_vertex(self, a_label: str, b_label: str): """ Add a directed edge between one vertex to another (same as add_directed_adjacent_vertex() and add_directed_edge()) Args: a_label: starting vertex label b_label: ending vertex label """ a = self.label_index[a_label] b = self.label_index[b_label] self.array[a][b] = True self.array[a][a] = True self.array[b][b] = True def df_traverse(self, start_label: str): """ Perform depth first traversal in an adjacency matrix Args: start_label: starting vertex label """ return self._df_rec_traverse(start_label, dict()) def _df_rec_traverse(self, start_label: str, visited): """ Helper method for depth first recursive traversal """ start_index = self.label_index[start_label] visited[start_index] = True print(self.labels[start_index]) for i in range(len(self.array)): if i not in visited and self.array[start_index][i]: self.df_rec_traverse(self.labels[i], visited) def bf_traverse(self, start_label: str): """ Perform breadth first traversal in an adjacency matrix Args: start_label: starting vertex label """ q = [] visited={} start_index = self.label_index[start_label] q.append(start_index) while len(q) > 0: current = q.pop(0) # equivalent of dequeue if current not in visited: visited[current] = True print(self.labels[current]) for i in range(len(self.array)): if self.array[current][i]: q.append(i) def print_graph(self): """ Print the contents of the graph """ print(" |", end="") for label in self.labels: print(f"{label:^3}", end=" ") print() print("----" * (len(self.array) + 1)) for r, row in enumerate(self.array): label = self.labels[r] print(f"{label:^3}|", end=""); for col in row: b = " T " if col else " " print(b, end=" ") print()
Methods
def add_adjacent_directed_vertex(self, a_label: str, b_label: str)
-
Add a directed edge between one vertex to another (same as add_directed_adjacent_vertex() and add_directed_edge())
Args
a_label
- starting vertex label
b_label
- ending vertex label
def add_adjacent_vertex(self, a_label: str, b_label: str)
-
Add an undirected edge between one vertex to another (same as add_adjacent_vertex())
Args
a_label
- starting vertex label
b_label
- ending vertex label
def add_directed_adjacent_vertex(self, a_label: str, b_label: str)
-
Add a directed edge between one vertex to another (same as add_adjacent_directed_vertex() and add_directed_edge())
Args
a_label
- starting vertex label
b_label
- ending vertex label
def add_directed_edge(self, a_label: str, b_label: str)
-
Add a directed edge between one vertex to another (same as add_directed_adjacent_vertex() and add_adjacent_directed_vertex())
Args
a_label
- starting vertex label
b_label
- ending vertex label
def add_edge(self, a_label: str, b_label: str)
-
Add an undirected edge between one vertex to another (same as add_edge())
Args
a_label
- starting vertex label
b_label
- ending vertex label
def bf_traverse(self, start_label: str)
-
Perform breadth first traversal in an adjacency matrix
Args
start_label
- starting vertex label
def df_traverse(self, start_label: str)
-
Perform depth first traversal in an adjacency matrix
Args
start_label
- starting vertex label
def print_graph(self)
-
Print the contents of the graph
class AdjacencyMatrixWeightedGraph (labels)
-
A weighted adjacency matrix graph implementation in Python (allows either directed or undirected representation)
Args
labels
- list of labels for each vertex
Expand source code
class AdjacencyMatrixWeightedGraph: """ A weighted adjacency matrix graph implementation in Python (allows either directed or undirected representation) """ def __init__(self, labels): """ Args: labels: list of labels for each vertex """ self.labels = labels self.label_index = { label: index for index, label in enumerate(labels) } node_count = len(self.labels) self.array = [[None for i in range(node_count)] for j in range(node_count)] def add_edge(self, a_label: str, b_label: str, weight): """ Add an undirected edge between one vertex to another (same as add_edge()) Args: a_label: starting vertex label b_label: ending vertex label weight: weight of the vertex """ self.add_adjacent_vertex(a_label, b_label, weight) def add_adjacent_vertex(self, a_label: str, b_label: str, weight): """ Add an undirected edge between one vertex to another (same as add_edge()) Args: a_label: starting vertex label b_label: ending vertex label weight: weight of the vertex """ a = self.label_index[a_label] b = self.label_index[b_label] self.array[a][b] = weight self.array[a][a] = 0 self.array[b][a] = weight self.array[b][b] = 0 def add_directed_edge(self, a_label: str, b_label: str, weight): """ Add a weighted directed edge between one vertex to another (same as add_adjacent_directed_vertex(), add_directed_adjacent_vertex()) Args: a_label: starting vertex label b_label: ending vertex label weight: weight of the vertex """ self.add_adjacent_directed_vertex(a_label, b_label, weight) def add_directed_adjacent_vertex(self, a_label: str, b_label: str, weight): """ Add a weighted directed edge between one vertex to another (same as add_directed_edge(), add_adjacent_directed_vertex()) Args: a_label: starting vertex label b_label: ending vertex label weight: weight of the vertex """ self.add_adjacent_directed_vertex(a_label, b_label, weight) def add_adjacent_directed_vertex(self, a_label: str, b_label: str, weight): """ Add a weighted directed edge between one vertex to another (same as add_directed_edge(), add_directed_adjacent_vertex()) Args: a_label: starting vertex label b_label: ending vertex label weight: weight of the vertex """ a = self.label_index[a_label] b = self.label_index[b_label] self.array[a][b] = weight self.array[a][a] = 0 self.array[b][b] = 0 def print_graph(self): """ Print the contents of the graph. """ print(" |", end="") for label in self.labels: print(f"{label:>3}", end=" ") print() print("----" * (len(self.array) + 1)) for r, row in enumerate(self.array): label = self.labels[r] print(f"{label:^3}|", end=""); for col in row: w = f"{col:3}" if col is not None else " " print(w, end=" ") print()
Methods
def add_adjacent_directed_vertex(self, a_label: str, b_label: str, weight)
-
Add a weighted directed edge between one vertex to another (same as add_directed_edge(), add_directed_adjacent_vertex())
Args
a_label
- starting vertex label
b_label
- ending vertex label
weight
- weight of the vertex
def add_adjacent_vertex(self, a_label: str, b_label: str, weight)
-
Add an undirected edge between one vertex to another (same as add_edge())
Args
a_label
- starting vertex label
b_label
- ending vertex label
weight
- weight of the vertex
def add_directed_adjacent_vertex(self, a_label: str, b_label: str, weight)
-
Add a weighted directed edge between one vertex to another (same as add_directed_edge(), add_adjacent_directed_vertex())
Args
a_label
- starting vertex label
b_label
- ending vertex label
weight
- weight of the vertex
def add_directed_edge(self, a_label: str, b_label: str, weight)
-
Add a weighted directed edge between one vertex to another (same as add_adjacent_directed_vertex(), add_directed_adjacent_vertex())
Args
a_label
- starting vertex label
b_label
- ending vertex label
weight
- weight of the vertex
def add_edge(self, a_label: str, b_label: str, weight)
-
Add an undirected edge between one vertex to another (same as add_edge())
Args
a_label
- starting vertex label
b_label
- ending vertex label
weight
- weight of the vertex
def print_graph(self)
-
Print the contents of the graph.
class Vertex (value)
-
A unweighted adjacency list vertex implementation in Python (allows either directed or undirected representation)
Args
value
- value of the vertex
Expand source code
class Vertex: pass
Methods
def add_adjacent_vertex(self, vertex: type[Vertex])
-
Add an undirected vertex to the adjacency list (same as add_edge()).
Args
vertex
- vertex to add
def add_directed_adjacent_vertex(self, vertex: type[Vertex])
-
Add a directed vertex to the adjacency list (same as add_directed_edge()).
Args
vertex
- vertex to add
def add_directed_edge(self, vertex: type[Vertex])
-
Add a directed vertex to the adjacency list (same as add_directed_adjacent_vertex()).
Args
vertex
- vertex to add
def add_edge(self, vertex: type[Vertex])
-
Add an undirected vertex to the adjacency list (same as add_adjacent_vertex()).
Args
vertex
- vertex to add
def bf_traverse(self)
-
Perform breadth first traversal.
def bfs(self, end)
-
Recursive breadth first search.
Args
end
- vertex to search for
Returns: Vertex in the graph None if not found.
def df_traverse(self)
-
Perform depth first traversal.
def dfs(self, end)
-
Recursive depth first search.
Args
end
- vertex to search for
Returns: Vertex in the graph None if not found.
def dfs_rec(self, current, end, visited=None)
-
helper depth first search recursive function
Returns: Vertex in the graph None if not found.
class WeightedVertex (value)
-
A weighted adjacency list vertex implementation in Python (allows either directed or undirected representation)
Args
value
- value of the vertex
Expand source code
class WeightedVertex: pass
Methods
def add_adjacent_vertex(self, vertex: type[WeightedVertex], weight)
-
Add a weighted edge to the adjacency list (same as add_directed_edge()).
Args
vertex
- vertex to add
weight
- weight of the vertex
def add_directed_adjacent_vertex(self, vertex: type[WeightedVertex], weight)
-
Add a weighted directed edge to the adjacency list (same as add_directed_edge()).
Args
vertex
- vertex to add
weight
- weight of the vertex
def add_directed_edge(self, vertex: type[WeightedVertex], weight)
-
Add a weighted directed edge to the adjacency list (same as add_directed_adjacent_vertex()).
Args
vertex
- vertex to add
weight
- weight of the vertex
def add_edge(self, vertex: type[WeightedVertex], weight)
-
Add a weighted directed edge to the adjacency list (same as add_adjacent_vertex()).
Args
vertex
- vertex to add
weight
- weight of the vertex
def bf_traverse(self, vertex: type[WeightedVertex])
-
breadth first traversal
Args
vertex
- starting vertex
def bfs(self, vertex: type[WeightedVertex], target)
-
breadth first search
Args
vertex
- startering vertex
target
- target value to search for
def df_traverse(self, vertex: type[WeightedVertex], visited={})
-
depth first traversal
Args
vertex
- starting vertex
visited
- dictionary of visited vertices
def dfs(self, target: type[WeightedVertex])
-
depth first search
Args
target
- target value to search for