forked from hofmannol/AlgoDatSoSe25
merge upstream
This commit is contained in:
commit
afec74f77f
5
data/aoc2212test.txt
Normal file
5
data/aoc2212test.txt
Normal file
@ -0,0 +1,5 @@
|
||||
Sabqponm
|
||||
abcryxxl
|
||||
accszExk
|
||||
acctuvwj
|
||||
abdefghi
|
15
data/aoc2416test.txt
Normal file
15
data/aoc2416test.txt
Normal file
@ -0,0 +1,15 @@
|
||||
###############
|
||||
#.......#....E#
|
||||
#.#.###.#.###.#
|
||||
#.....#.#...#.#
|
||||
#.###.#####.#.#
|
||||
#.#.#.......#.#
|
||||
#.#.#####.###.#
|
||||
#...........#.#
|
||||
###.#.#####.#.#
|
||||
#...#.....#.#.#
|
||||
#.#.#.###.#.#.#
|
||||
#.....#...#.#.#
|
||||
#.###.#.#.#.#.#
|
||||
#S..#.....#...#
|
||||
###############
|
8
data/elektro.txt
Normal file
8
data/elektro.txt
Normal file
@ -0,0 +1,8 @@
|
||||
"Höhleneingang";"Ost/West-Passage";5
|
||||
"Höhleneingang";"Nord/Süd-Passage";3
|
||||
"Nord/Süd-Passage";"Nebelraum";7
|
||||
"Steiniger Pfad";"Ost/West-Passage";2
|
||||
"Ost/West-Passage";"Schwefelgewölbe";4
|
||||
"Schwefelgewölbe";"Steiniger Pfad";1
|
||||
"Schatzkammer";"Nebelraum";2
|
||||
"Steiniger Pfad";"Schatzkammer";6
|
9
data/labyrinth.txt
Normal file
9
data/labyrinth.txt
Normal file
@ -0,0 +1,9 @@
|
||||
xxxxxxxxxxxxxxxxxxxxx
|
||||
x x
|
||||
x S x
|
||||
x x
|
||||
x xxxxxxxx x
|
||||
x x
|
||||
x x
|
||||
x A x
|
||||
xxxxxxxxxxxxxxxxxxxxx
|
5
data/labyrinth1.txt
Normal file
5
data/labyrinth1.txt
Normal file
@ -0,0 +1,5 @@
|
||||
xxxxxAxxxxxxxxx
|
||||
x xSx
|
||||
xxxxxxxxxx xx x
|
||||
x x
|
||||
xxxxxxxxxxxxxxx
|
@ -34,27 +34,9 @@ def fs(x: MemoryCell, i: Literal, m: Literal) -> Literal:
|
||||
return position % m
|
||||
|
||||
|
||||
class TestHashTableOpenAddressing(unittest.TestCase):
|
||||
|
||||
def test_hash_function(self):
|
||||
x = MemoryCell(22)
|
||||
m = Literal(20)
|
||||
self.assertEqual(11, h(x, m).value)
|
||||
|
||||
def test_probe_function(self):
|
||||
x = MemoryCell(22)
|
||||
i = Literal(0)
|
||||
m = Literal(20)
|
||||
self.assertEqual(11, f(x, i, m).value)
|
||||
i = Literal(1)
|
||||
self.assertEqual(17, f(x, i, m).value)
|
||||
i = Literal(2)
|
||||
self.assertEqual(13, f(x, i, m).value)
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
#unittest.main()
|
||||
|
||||
print("*** Aufgabe 3 ***")
|
||||
size = Literal(20)
|
||||
|
37
praktika/08_graph/schatz.py
Normal file
37
praktika/08_graph/schatz.py
Normal file
@ -0,0 +1,37 @@
|
||||
import re
|
||||
from utils.project_dir import get_path
|
||||
from vorlesung.L08_graphen.graph import Graph, AdjacencyListGraph, AdjacencyMatrixGraph
|
||||
|
||||
|
||||
def read_cave_into_graph(graph: Graph, filename: str):
|
||||
"""Read a cave description from a file and insert it into the given graph."""
|
||||
filename = get_path(filename)
|
||||
with open(filename, "r") as file:
|
||||
lines = file.readlines()
|
||||
for line in lines:
|
||||
# match a line with two node names and an optional direction
|
||||
m = re.match(r"(^\s*\"(.*)\"\s*([<>]*)\s*\"(.*)\"\s*)", line)
|
||||
if m:
|
||||
startnode = m.group(2)
|
||||
endnode = m.group(4)
|
||||
opcode = m.group(3)
|
||||
graph.insert_vertex(startnode)
|
||||
graph.insert_vertex(endnode)
|
||||
if '>' in opcode:
|
||||
graph.connect(startnode, endnode)
|
||||
if '<' in opcode:
|
||||
graph.connect(endnode, startnode)
|
||||
|
||||
|
||||
graph = AdjacencyListGraph()
|
||||
# graph = AdjacencyMatrixGraph()
|
||||
read_cave_into_graph(graph, "data/hoehle.txt")
|
||||
_, predecessor_map = graph.bfs('Höhleneingang')
|
||||
path = graph.path('Schatzkammer', predecessor_map)
|
||||
print(path)
|
||||
_, predecessor_map = graph.bfs('Schatzkammer')
|
||||
path = graph.path('Höhleneingang', predecessor_map)
|
||||
print(path)
|
||||
graph.graph("Höhle")
|
||||
|
||||
|
59
praktika/09_aoc/rendeer.py
Normal file
59
praktika/09_aoc/rendeer.py
Normal file
@ -0,0 +1,59 @@
|
||||
from utils.project_dir import get_path
|
||||
from vorlesung.L08_graphen.graph import AdjacencyListGraph
|
||||
|
||||
DIRECTIONS = [(1,0), (0, 1), (-1, 0), (0, -1)]
|
||||
|
||||
class D16Solution:
|
||||
|
||||
def __init__(self):
|
||||
with open(get_path("data/aoc2416.txt"), "r") as file:
|
||||
self.puzzle = [line.strip() for line in file]
|
||||
self.cells = set()
|
||||
self.start = None
|
||||
self.end = None
|
||||
|
||||
def get_cells_start_end(self):
|
||||
for row in range(len(self.puzzle)):
|
||||
for col in range(len(self.puzzle[row])):
|
||||
if self.puzzle[row][col] != '#':
|
||||
self.cells.add((col, row))
|
||||
if self.puzzle[row][col] == 'S':
|
||||
self.start = (col, row)
|
||||
if self.puzzle[row][col] == 'E':
|
||||
self.end = (col, row)
|
||||
|
||||
def get_label(self, cell, direction):
|
||||
"""Generate a label for a cell based on its coordinates and direction."""
|
||||
return f"{cell[0]},{cell[1]}_{direction}"
|
||||
|
||||
def create_graph(self):
|
||||
graph = AdjacencyListGraph()
|
||||
for cell in self.cells:
|
||||
for direction in DIRECTIONS:
|
||||
label = self.get_label(cell, direction)
|
||||
graph.insert_vertex(label)
|
||||
for cell in self.cells:
|
||||
for d, direction in enumerate(DIRECTIONS):
|
||||
label = self.get_label(cell, direction)
|
||||
dx, dy = direction
|
||||
neighbor = (cell[0] + dx, cell[1] + dy)
|
||||
if neighbor in self.cells:
|
||||
graph.connect(label, self.get_label(neighbor, direction))
|
||||
direction_left = DIRECTIONS[(d - 1) % 4]
|
||||
direction_right = DIRECTIONS[(d + 1) % 4]
|
||||
graph.connect(label, self.get_label(cell, direction_left), 1000)
|
||||
graph.connect(label, self.get_label(cell, direction_right), 1000)
|
||||
return graph
|
||||
|
||||
if __name__ == "__main__":
|
||||
solution = D16Solution()
|
||||
solution.get_cells_start_end()
|
||||
graph = solution.create_graph()
|
||||
start = solution.get_label(solution.start, DIRECTIONS[0])
|
||||
print(f"Start: {start}")
|
||||
distance_map, predecessor_map = graph.dijkstra(start)
|
||||
end_labels = [solution.get_label(solution.end, direction) for direction in DIRECTIONS]
|
||||
end_vertices = [graph.get_vertex(label) for label in end_labels]
|
||||
min_weight = min([distance_map[vertex] for vertex in end_vertices])
|
||||
print(f"Minimum distance to End {solution.end}: {min_weight}")
|
||||
|
40
utils/priority_queue.py
Normal file
40
utils/priority_queue.py
Normal file
@ -0,0 +1,40 @@
|
||||
import heapq
|
||||
|
||||
class PriorityQueue:
|
||||
def __init__(self):
|
||||
self.heap = []
|
||||
self.entry_finder = {} # map: item -> [priority, item]
|
||||
self.REMOVED = '<removed>'
|
||||
self.counter = 0 # unique sequence count to break ties
|
||||
|
||||
def add_or_update(self, item, priority):
|
||||
if item in self.entry_finder:
|
||||
self.remove(item)
|
||||
count = self.counter
|
||||
entry = [priority, count, item]
|
||||
self.entry_finder[item] = entry
|
||||
heapq.heappush(self.heap, entry)
|
||||
self.counter += 1
|
||||
|
||||
def remove(self, item):
|
||||
entry = self.entry_finder.pop(item)
|
||||
entry[-1] = self.REMOVED # mark as removed
|
||||
|
||||
def pop(self):
|
||||
while self.heap:
|
||||
priority, count, item = heapq.heappop(self.heap)
|
||||
if item != self.REMOVED:
|
||||
del self.entry_finder[item]
|
||||
return item, priority
|
||||
return None
|
||||
|
||||
if __name__ == "__main__":
|
||||
pq = PriorityQueue()
|
||||
pq.add_or_update('task1', 1)
|
||||
pq.add_or_update('task2', float('inf'))
|
||||
pq.add_or_update('task3', float('inf'))
|
||||
|
||||
print(pq.pop()) # Should print ('task1', 1)
|
||||
pq.add_or_update('task2', 0) # Update priority of 'task1'
|
||||
print(pq.pop()) # Should print ('task2', 0)
|
||||
print(pq.pop()) # Should print ('task3', 3)
|
@ -1,6 +1,4 @@
|
||||
from vorlesung.L05_binaere_baeume.bin_tree_node import BinaryTreeNode
|
||||
from utils.memory_manager import MemoryManager
|
||||
from utils.memory_array import MemoryArray
|
||||
from utils.project_dir import get_path
|
||||
from datetime import datetime
|
||||
import graphviz
|
||||
|
0
vorlesung/L08_graphen/__init__.py
Normal file
0
vorlesung/L08_graphen/__init__.py
Normal file
45
vorlesung/L08_graphen/aoc2212.py
Normal file
45
vorlesung/L08_graphen/aoc2212.py
Normal file
@ -0,0 +1,45 @@
|
||||
from vorlesung.L08_graphen.graph import Graph, AdjacencyMatrixGraph
|
||||
from utils.project_dir import get_path
|
||||
|
||||
graph = AdjacencyMatrixGraph()
|
||||
start = ""
|
||||
end = ""
|
||||
|
||||
def read_file(filename: str = "data/aoc2212.txt"):
|
||||
"""Read a file and return the content as a string."""
|
||||
|
||||
def adjust_char(char):
|
||||
"""Adjust character for comparison."""
|
||||
if char == 'S':
|
||||
return 'a'
|
||||
elif char == 'E':
|
||||
return 'z'
|
||||
return char
|
||||
|
||||
global start, end
|
||||
with open(get_path(filename), "r") as file:
|
||||
quest = file.read().strip().splitlines()
|
||||
for row, line in enumerate(quest):
|
||||
for col, char in enumerate(line):
|
||||
label = f"{row},{col}"
|
||||
graph.insert_vertex(label)
|
||||
if char == "S":
|
||||
start = label
|
||||
if char == "E":
|
||||
end = label
|
||||
for row, line in enumerate(quest):
|
||||
for col, char in enumerate(line):
|
||||
for neighbor in [(row - 1, col), (row, col - 1), (row + 1, col), (row, col + 1)]:
|
||||
if 0 <= neighbor[0] < len(quest) and 0 <= neighbor[1] < len(line):
|
||||
if ord(adjust_char(quest[neighbor[0]][neighbor[1]])) <= ord(adjust_char(char)) + 1:
|
||||
label1 = f"{row},{col}"
|
||||
label2 = f"{neighbor[0]},{neighbor[1]}"
|
||||
graph.connect(label1, label2)
|
||||
|
||||
|
||||
# Lösung des Adventskalenders 2022, Tag 12
|
||||
read_file("data/aoc2212test.txt")
|
||||
graph.graph()
|
||||
distance_map, predecessor_map = graph.bfs(start)
|
||||
print(distance_map[graph.get_vertex(end)])
|
||||
print(graph.path(end, predecessor_map))
|
303
vorlesung/L08_graphen/graph.py
Normal file
303
vorlesung/L08_graphen/graph.py
Normal file
@ -0,0 +1,303 @@
|
||||
from collections import deque
|
||||
from typing import List
|
||||
from enum import Enum
|
||||
import graphviz
|
||||
from datetime import datetime
|
||||
from utils.project_dir import get_path
|
||||
from utils.priority_queue import PriorityQueue
|
||||
|
||||
|
||||
class NodeColor(Enum):
|
||||
"""Enumeration for node colors in a graph traversal."""
|
||||
WHITE = 1 # WHITE: not visited
|
||||
GRAY = 2 # GRAY: visited but not all neighbors visited
|
||||
BLACK = 3 # BLACK: visited and all neighbors visited
|
||||
|
||||
|
||||
class Vertex:
|
||||
"""A vertex in a graph."""
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
def __str__(self):
|
||||
return str(self.value)
|
||||
|
||||
def __repr__(self):
|
||||
return f"Vertex({self.value})"
|
||||
|
||||
|
||||
|
||||
class Graph:
|
||||
"""A graph."""
|
||||
def insert_vertex(self, name: str):
|
||||
raise NotImplementedError("Please implement this method in subclass")
|
||||
|
||||
def connect(self, name1: str, name2: str, weight: float = 1):
|
||||
raise NotImplementedError("Please implement this method in subclass")
|
||||
|
||||
def all_vertices(self) -> List[Vertex]:
|
||||
raise NotImplementedError("Please implement this method in subclass")
|
||||
|
||||
def get_vertex(self, name: str) -> Vertex:
|
||||
raise NotImplementedError("Please implement this method in subclass")
|
||||
|
||||
def get_adjacent_vertices(self, name: str) -> List[Vertex]:
|
||||
raise NotImplementedError("Please implement this method in subclass")
|
||||
|
||||
def get_adjacent_vertices_with_weight(self, name: str) -> List[tuple[Vertex, float]]:
|
||||
raise NotImplementedError("Please implement this method in subclass")
|
||||
|
||||
def all_edges(self) -> List[tuple[str, str, float]]:
|
||||
raise NotImplementedError("Please implement this method in subclass")
|
||||
|
||||
def bfs(self, start_name: str):
|
||||
"""
|
||||
Perform a breadth-first search starting at the given vertex.
|
||||
:param start_name: the name of the vertex to start at
|
||||
:return: a tuple of two dictionaries, the first mapping vertices to distances from the start vertex,
|
||||
the second mapping vertices to their predecessors in the traversal tree
|
||||
"""
|
||||
|
||||
color_map = {} # maps vertices to their color
|
||||
distance_map = {} # maps vertices to their distance from the start vertex
|
||||
predecessor_map = {} # maps vertices to their predecessor in the traversal tree
|
||||
|
||||
# Initialize the maps
|
||||
for vertex in self.all_vertices():
|
||||
color_map[vertex] = NodeColor.WHITE
|
||||
distance_map[vertex] = None
|
||||
predecessor_map[vertex] = None
|
||||
|
||||
# Start at the given vertex
|
||||
start_node = self.get_vertex(start_name)
|
||||
color_map[start_node] = NodeColor.GRAY
|
||||
distance_map[start_node] = 0
|
||||
|
||||
# Initialize the queue with the start vertex
|
||||
queue = deque()
|
||||
queue.append(start_node)
|
||||
|
||||
# Process the queue
|
||||
while len(queue) > 0:
|
||||
vertex = queue.popleft()
|
||||
for dest in self.get_adjacent_vertices(vertex.value):
|
||||
if color_map[dest] == NodeColor.WHITE:
|
||||
color_map[dest] = NodeColor.GRAY
|
||||
distance_map[dest] = distance_map[vertex] + 1
|
||||
predecessor_map[dest] = vertex
|
||||
queue.append(dest)
|
||||
color_map[vertex] = NodeColor.BLACK
|
||||
|
||||
# Return the distance and predecessor maps
|
||||
return distance_map, predecessor_map
|
||||
|
||||
def dfs(self):
|
||||
"""
|
||||
Perform a depth-first search starting at the first vertex.
|
||||
:return: a tuple of two dictionaries, the first mapping vertices to distances from the start vertex,
|
||||
the second mapping vertices to their predecessors in the traversal tree
|
||||
"""
|
||||
color_map : dict[Vertex, NodeColor]= {}
|
||||
enter_map : dict[Vertex, int] = {}
|
||||
leave_map : dict[Vertex, int] = {}
|
||||
predecessor_map : dict[Vertex, Vertex | None] = {}
|
||||
white_vertices = set(self.all_vertices())
|
||||
time_counter = 0
|
||||
|
||||
def dfs_visit(vertex):
|
||||
nonlocal time_counter
|
||||
color_map[vertex] = NodeColor.GRAY
|
||||
white_vertices.remove(vertex)
|
||||
time_counter += 1
|
||||
enter_map[vertex] = time_counter
|
||||
for dest in self.get_adjacent_vertices(vertex.value):
|
||||
if color_map[dest] == NodeColor.WHITE:
|
||||
predecessor_map[dest] = vertex
|
||||
dfs_visit(dest)
|
||||
color_map[vertex] = NodeColor.BLACK
|
||||
time_counter += 1
|
||||
leave_map[vertex] = time_counter
|
||||
|
||||
# Initialize the maps
|
||||
for vertex in self.all_vertices():
|
||||
color_map[vertex] = NodeColor.WHITE
|
||||
predecessor_map[vertex] = None
|
||||
|
||||
while white_vertices:
|
||||
v = white_vertices.pop()
|
||||
dfs_visit(v)
|
||||
|
||||
return enter_map, leave_map, predecessor_map
|
||||
|
||||
|
||||
def path(self, destination, map):
|
||||
"""
|
||||
Compute the path from the start vertex to the given destination vertex.
|
||||
The map parameter is the predecessor map
|
||||
"""
|
||||
path = []
|
||||
destination_node = self.get_vertex(destination)
|
||||
while destination_node is not None:
|
||||
path.insert(0, destination_node.value)
|
||||
destination_node = map[destination_node]
|
||||
return path
|
||||
|
||||
def graph(self, filename: str = "Graph"):
|
||||
dot = graphviz.Digraph( name=filename,
|
||||
node_attr={"fontname": "Arial"},
|
||||
format="pdf" )
|
||||
for vertex in self.all_vertices():
|
||||
dot.node(str(id(vertex)), label=str(vertex.value))
|
||||
for edge in self.all_edges():
|
||||
dot.edge(str(id(self.get_vertex(edge[0]))), str(id(self.get_vertex(edge[1]))), label=str(edge[2]))
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
filename = f"{filename}_{timestamp}.gv"
|
||||
filename = get_path(filename)
|
||||
dot.render(filename)
|
||||
|
||||
def dijkstra(self, start_name: str) -> tuple[dict[Vertex, float], dict[Vertex, Vertex | None]]:
|
||||
"""
|
||||
Führt den Dijkstra-Algorithmus für kürzeste Pfade durch, implementiert mit Knotenfarben.
|
||||
|
||||
Args:
|
||||
start_name: Name des Startknotens
|
||||
|
||||
Returns:
|
||||
Ein Tupel aus zwei Dictionaries:
|
||||
- distance_map: Abbildung von Knoten auf ihre kürzeste Distanz vom Startknoten
|
||||
- predecessor_map: Abbildung von Knoten auf ihre Vorgänger im kürzesten Pfad
|
||||
"""
|
||||
|
||||
def relax(vertex, dest, weight):
|
||||
"""
|
||||
Entspannt die Kante zwischen vertex und dest.
|
||||
Aktualisiert die Distanz und den Vorgänger, wenn ein kürzerer Pfad gefunden wird.
|
||||
"""
|
||||
if distance_map[vertex] + weight < distance_map[dest]:
|
||||
distance_map[dest] = distance_map[vertex] + weight
|
||||
predecessor_map[dest] = vertex
|
||||
queue.add_or_update(dest, distance_map[dest])
|
||||
|
||||
# Initialisierung der Maps
|
||||
distance_map = {} # Speichert kürzeste Distanzen
|
||||
predecessor_map = {} # Speichert Vorgänger
|
||||
|
||||
# Initialisiere alle Knoten
|
||||
queue = PriorityQueue()
|
||||
for vertex in self.all_vertices():
|
||||
distance_map[vertex] = float('inf') # Initiale Distanz unendlich
|
||||
predecessor_map[vertex] = None # Initialer Vorgänger None
|
||||
queue.add_or_update(vertex, distance_map[vertex]) # Füge Knoten zur Prioritätswarteschlange hinzu
|
||||
|
||||
|
||||
|
||||
# Setze Startknoten
|
||||
start_node = self.get_vertex(start_name)
|
||||
distance_map[start_node] = 0
|
||||
queue.add_or_update(start_node, distance_map[start_node])
|
||||
|
||||
while True:
|
||||
entry = queue.pop()
|
||||
if entry is None:
|
||||
break
|
||||
vertex = entry[0]
|
||||
for dest, weight in self.get_adjacent_vertices_with_weight(vertex.value):
|
||||
relax(vertex, dest, weight)
|
||||
return distance_map, predecessor_map
|
||||
|
||||
|
||||
class AdjacencyListGraph(Graph):
|
||||
"""A graph implemented as an adjacency list."""
|
||||
def __init__(self):
|
||||
self.adjacency_map = {} # maps vertex names to lists of adjacent vertices
|
||||
self.vertex_map = {} # maps vertex names to vertices
|
||||
|
||||
def insert_vertex(self, name: str):
|
||||
if name not in self.vertex_map:
|
||||
self.vertex_map[name] = Vertex(name)
|
||||
if name not in self.adjacency_map:
|
||||
self.adjacency_map[name] = []
|
||||
|
||||
def connect(self, name1: str, name2: str, weight: float = 1):
|
||||
adjacency_list = self.adjacency_map[name1]
|
||||
dest = self.vertex_map[name2]
|
||||
adjacency_list.append((dest, weight))
|
||||
|
||||
def all_vertices(self) -> List[Vertex]:
|
||||
return list(self.vertex_map.values())
|
||||
|
||||
def get_vertex(self, name: str) -> Vertex:
|
||||
return self.vertex_map[name]
|
||||
|
||||
def get_adjacent_vertices(self, name: str) -> List[Vertex]:
|
||||
return list(map(lambda x: x[0], self.adjacency_map[name]))
|
||||
|
||||
def get_adjacent_vertices_with_weight(self, name: str) -> List[tuple[Vertex, float]]:
|
||||
return self.adjacency_map[name]
|
||||
|
||||
def all_edges(self) -> List[tuple[str, str, float]]:
|
||||
result = []
|
||||
for name in self.adjacency_map:
|
||||
for (dest, weight) in self.adjacency_map[name]:
|
||||
result.append((name, dest.value, weight))
|
||||
return result
|
||||
|
||||
|
||||
|
||||
|
||||
class AdjacencyMatrixGraph(Graph):
|
||||
"""A graph implemented as an adjacency matrix."""
|
||||
def __init__(self):
|
||||
self.index_map = {} # maps vertex names to indices
|
||||
self.vertex_list = [] # list of vertices
|
||||
self.adjacency_matrix = [] # adjacency matrix
|
||||
|
||||
def insert_vertex(self, name: str):
|
||||
if name not in self.index_map:
|
||||
self.index_map[name] = len(self.vertex_list)
|
||||
self.vertex_list.append(Vertex(name))
|
||||
for row in self.adjacency_matrix: # add a new column to each row
|
||||
row.append(None)
|
||||
self.adjacency_matrix.append([None] * len(self.vertex_list)) # add a new row
|
||||
|
||||
def connect(self, name1: str, name2: str, weight: float = 1):
|
||||
index1 = self.index_map[name1]
|
||||
index2 = self.index_map[name2]
|
||||
self.adjacency_matrix[index1][index2] = weight
|
||||
|
||||
|
||||
def all_vertices(self) -> List[Vertex]:
|
||||
return self.vertex_list
|
||||
|
||||
def get_vertex(self, name: str) -> Vertex:
|
||||
index = self.index_map[name]
|
||||
return self.vertex_list[index]
|
||||
|
||||
def get_adjacent_vertices(self, name: str) -> List[Vertex]:
|
||||
index = self.index_map[name]
|
||||
result = []
|
||||
for i in range(len(self.vertex_list)):
|
||||
if self.adjacency_matrix[index][i] is not None:
|
||||
name = self.vertex_list[i].value
|
||||
result.append(self.get_vertex(name))
|
||||
return result
|
||||
|
||||
def get_adjacent_vertices_with_weight(self, name: str) -> List[tuple[Vertex, float]]:
|
||||
index = self.index_map[name]
|
||||
result = []
|
||||
for i in range(len(self.vertex_list)):
|
||||
if self.adjacency_matrix[index][i] is not None:
|
||||
name = self.vertex_list[i].value
|
||||
result.append((self.get_vertex(name), self.adjacency_matrix[index][i]))
|
||||
return result
|
||||
|
||||
def all_edges(self) -> List[tuple[str, str, float]]:
|
||||
result = []
|
||||
for i in range(len(self.vertex_list)):
|
||||
for j in range(len(self.vertex_list)):
|
||||
if self.adjacency_matrix[i][j] is not None:
|
||||
result.append((self.vertex_list[i].value, self.vertex_list[j].value, self.adjacency_matrix[i][j]))
|
||||
return result
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user