from SoSe24.algodat.foundation import AlgoDatArray, AlgoDatValue, read_int_sequence | |||||
from SoSe24.lec04_trees.bin_tree import BinTree, BinTreeNode | |||||
from time import perf_counter as pfc | |||||
class AVLTreeNode(BinTreeNode): | |||||
def __init__(self, value: AlgoDatValue): | |||||
super().__init__(value) | |||||
self.parent = None | |||||
self.balance = 0 | |||||
def update_balance(self): | |||||
left_height = self.left.height() if self.left else 0 | |||||
right_height = self.right.height() if self.right else 0 | |||||
self.balance = right_height - left_height | |||||
def right_rotate(self) -> BinTreeNode: | |||||
new_root = self.left | |||||
new_root.parent = self.parent | |||||
self.left = new_root.right | |||||
if self.left: | |||||
self.left.parent = self | |||||
new_root.right = self | |||||
self.parent = new_root | |||||
if new_root.parent: | |||||
if new_root.parent.left == self: | |||||
new_root.parent.left = new_root | |||||
else: | |||||
new_root.parent.right = new_root | |||||
self.update_balance() | |||||
new_root.update_balance() | |||||
return new_root | |||||
def left_rotate(self) -> BinTreeNode: | |||||
new_root = self.right | |||||
new_root.parent = self.parent | |||||
self.right = new_root.left | |||||
if self.right: | |||||
self.right.parent = self | |||||
new_root.left = self | |||||
self.parent = new_root | |||||
if new_root.parent: | |||||
if new_root.parent.left == self: | |||||
new_root.parent.left = new_root | |||||
else: | |||||
new_root.parent.right = new_root | |||||
self.update_balance() | |||||
new_root.update_balance() | |||||
return new_root | |||||
def right_left_rotate(self) -> BinTreeNode: | |||||
self.right = self.right.right_rotate() | |||||
return self.left_rotate() | |||||
def left_right_rotate(self) -> BinTreeNode: | |||||
self.left = self.left.left_rotate() | |||||
return self.right_rotate() | |||||
class AVLTree(BinTree): | |||||
def new_node(self, value: AlgoDatValue): | |||||
return AVLTreeNode(value) | |||||
def balance(self, node: AVLTreeNode): | |||||
node.update_balance() | |||||
if node.balance == -2: | |||||
if node.left.balance <= 0: | |||||
node = node.right_rotate() | |||||
else: | |||||
node = node.left_right_rotate() | |||||
elif node.balance == 2: | |||||
if node.right.balance >= 0: | |||||
node = node.left_rotate() | |||||
else: | |||||
node = node.right_left_rotate() | |||||
if node.parent: | |||||
self.balance(node.parent) | |||||
else: | |||||
self.root = node | |||||
def insert(self, value: AlgoDatValue): | |||||
node, parent = super().insert(value) | |||||
node.parent = parent | |||||
if parent: | |||||
self.balance(parent) | |||||
return node, parent | |||||
def delete(self, value: AlgoDatValue): | |||||
node, parent = super().delete(value) | |||||
if node: | |||||
node.parent = parent | |||||
if parent: | |||||
self.balance(parent) | |||||
if __name__ == "__main__": | |||||
z = read_int_sequence("../../seq0.txt") | |||||
print(z, len(z)) | |||||
start = pfc() | |||||
tree = AVLTree() | |||||
for i in z: | |||||
tree.insert(i) | |||||
tree.walk() | |||||
tree.tree_walk() | |||||
tree.levelwalk() | |||||
tree.graph_walk() | |||||
tree.delete(AlgoDatValue(46)) | |||||
tree.delete(AlgoDatValue(48)) | |||||
#tree.graph_walk() | |||||
print(f"Dauer: {pfc() - start:.4f}s") | |||||
AlgoDatValue.summary() |
from SoSe24.algodat.foundation import AlgoDatArray, AlgoDatValue, read_int_sequence, read_int_sequence_limited | |||||
import matplotlib | |||||
matplotlib.use('TkAgg') | |||||
import matplotlib.pyplot as plt | |||||
import avl_tree as avl | |||||
if __name__ == "__main__": | |||||
filename = "../../seq3_sorted.txt" | |||||
#filename = "../../seq3.txt" | |||||
dummy = read_int_sequence(filename) | |||||
n = len(dummy) | |||||
step = n // 100 | |||||
memory_values = [] | |||||
compare_values = [] | |||||
for right_end in range(1, n, step): | |||||
AlgoDatValue.reset() | |||||
z = read_int_sequence_limited(filename, right_end) | |||||
tree = avl.AVLTree() | |||||
for i in z: | |||||
tree.insert(i) | |||||
memory_values.append(AlgoDatValue.memory) | |||||
compare_values.append(AlgoDatValue.compare) | |||||
plt.plot(range(1, n, step), memory_values, 'b', label='Memory') | |||||
plt.plot(range(1, n, step), compare_values, 'r', label='Compare') | |||||
plt.legend() | |||||
plt.show() |
from SoSe24.algodat.foundation import AlgoDatArray, AlgoDatValue, read_int_sequence | |||||
from time import perf_counter as pfc | |||||
class BTreeNode: | |||||
def __init__(self, m: int): | |||||
self.n = 0 | |||||
self.leaf = True | |||||
self.keys = AlgoDatArray(2 * m - 1) | |||||
self.children = [None] * (2 * m) | |||||
def __str__(self): | |||||
return "(" + " ".join([str(self.keys[i]) for i in range(self.n)]) + ")" | |||||
class BTree: | |||||
def __init__(self, m: int): | |||||
self.m = m | |||||
self.root = BTreeNode(m) | |||||
def search(self, key: AlgoDatValue, start: BTreeNode = None) -> BTreeNode: | |||||
if not start: | |||||
start = self.root | |||||
i = 0 | |||||
while i < start.n and key > start.keys[i]: | |||||
i += 1 | |||||
if i < start.n and key == start.keys[i]: | |||||
return start | |||||
if start.leaf: | |||||
return None | |||||
return self.search(key, start.children[i]) | |||||
def split_child(self, parent: BTreeNode, i: int): | |||||
child = parent.children[i] | |||||
h = BTreeNode(self.m) | |||||
h.leaf = child.leaf | |||||
h.n = self.m - 1 | |||||
for j in range(self.m - 1): | |||||
h.keys[j] = child.keys[j + self.m] | |||||
if not h.leaf: | |||||
for j in range(self.m): | |||||
h.children[j] = child.children[j + self.m] | |||||
for j in range(self.m, child.n + 1): | |||||
child.children[j] = None | |||||
child.n = self.m - 1 | |||||
for j in range(parent.n, i, -1): | |||||
parent.children[j + 1] = parent.children[j] | |||||
parent.keys[j] = parent.keys[j - 1] | |||||
parent.children[i + 1] = h | |||||
parent.keys[i] = child.keys[self.m - 1] | |||||
parent.n += 1 | |||||
def insert(self, k: AlgoDatValue): | |||||
r = self.root | |||||
if r.n == 2 * self.m - 1: | |||||
h = BTreeNode(self.m) | |||||
self.root = h | |||||
h.leaf = False | |||||
h.n = 0 | |||||
h.children[0] = r | |||||
self.split_child(h, 0) | |||||
self.insert_in_node(h, k) | |||||
else: | |||||
self.insert_in_node(r, k) | |||||
def insert_in_node(self, start: BTreeNode, k: AlgoDatValue): | |||||
i = start.n | |||||
if start.leaf: | |||||
while i >= 1 and k < start.keys[i-1]: | |||||
start.keys[i] = start.keys[i-1] | |||||
i -= 1 | |||||
start.keys[i] = k | |||||
start.n += 1 | |||||
else: | |||||
j = 0 | |||||
while j < start.n and k > start.keys[j]: | |||||
j += 1 | |||||
if start.children[j].n == 2 * self.m - 1: | |||||
self.split_child(start, j) | |||||
if k > start.keys[j]: | |||||
j += 1 | |||||
self.insert_in_node(start.children[j], k) | |||||
def walk(self, start: BTreeNode = None): | |||||
if not start: | |||||
start = self.root | |||||
i = 0 | |||||
while i < start.n: | |||||
if not start.leaf: | |||||
self.walk(start.children[i]) | |||||
print(start.keys[i], end=" ") | |||||
i += 1 | |||||
if not start.leaf: | |||||
self.walk(start.children[i]) | |||||
def height(self, start: BTreeNode = None): | |||||
if not start: | |||||
start = self.root | |||||
if start.leaf: | |||||
return 0 | |||||
return 1 + self.height(start.children[0]) | |||||
def graph_walk(self): | |||||
queue = [ self.root ] | |||||
with open("../../btree.gv", "w") as file: | |||||
file.write("digraph BTree {\n") | |||||
file.write(" node [fontname=\"Arial\"];\n") | |||||
while queue: | |||||
current = queue.pop(0) | |||||
p = str(current) | |||||
file.write(f'"{p}"; \n') | |||||
i = 0 | |||||
while i <= current.n: | |||||
if not current.leaf: | |||||
queue.append(current.children[i]) | |||||
c = str(current.children[i]) | |||||
file.write(f'"{p}" -> "{c}";\n') | |||||
i += 1 | |||||
file.write("}") | |||||
if __name__ == "__main__": | |||||
z = read_int_sequence("../../seq2.txt") | |||||
start = pfc() | |||||
tree = BTree(3) | |||||
for i in z: | |||||
tree.insert(i) | |||||
print(f"Height: {tree.height()}") | |||||
tree.walk() | |||||
tree.graph_walk() | |||||
s = tree.search(AlgoDatValue(0)) | |||||
print(f"\nKnoten mit 0: {str(s)}") | |||||
print(f"Dauer: {pfc() - start:.4f}s") | |||||
AlgoDatValue.summary() |
from SoSe24.algodat.foundation import AlgoDatArray, AlgoDatValue, read_int_sequence | |||||
from time import perf_counter as pfc | |||||
class BinTreeNode: | |||||
def __init__(self, value: AlgoDatValue): | |||||
self.value = value | |||||
self.left = None | |||||
self.right = None | |||||
def __str__(self): | |||||
return f"{self.value}" | |||||
def height(self) -> int: | |||||
left_height = self.left.height() if self.left else 0 | |||||
right_height = self.right.height() if self.right else 0 | |||||
return 1 + max(left_height, right_height) | |||||
class BinTree: | |||||
def __init__(self): | |||||
self.root = None | |||||
def new_node(self, value: AlgoDatValue) -> BinTreeNode: | |||||
return BinTreeNode(value) | |||||
def insert(self, value: AlgoDatValue) -> (BinTreeNode, BinTreeNode): | |||||
if not self.root: | |||||
self.root = self.new_node(value) | |||||
return self.root, None | |||||
current = self.root | |||||
while True: | |||||
if value < current.value: | |||||
if current.left: | |||||
current = current.left | |||||
else: | |||||
current.left = self.new_node(value) | |||||
return current.left, current | |||||
elif value >= current.value: | |||||
if current.right: | |||||
current = current.right | |||||
else: | |||||
current.right = self.new_node(value) | |||||
return current.right, current | |||||
else: | |||||
return None, None | |||||
def search(self, value: AlgoDatValue) -> BinTreeNode: | |||||
current = self.root | |||||
while current: | |||||
if value < current.value: | |||||
current = current.left | |||||
elif value > current.value: | |||||
current = current.right | |||||
else: | |||||
return current | |||||
return None | |||||
def delete(self, value: AlgoDatValue): | |||||
parent = None | |||||
current = self.root | |||||
while current: | |||||
if value < current.value: | |||||
parent = current | |||||
current = current.left | |||||
elif value >= current.value: | |||||
parent = current | |||||
current = current.right | |||||
else: | |||||
break | |||||
else: | |||||
return | |||||
if current.left and current.right: | |||||
parent = current | |||||
successor = current.right | |||||
while successor.left: | |||||
parent = successor | |||||
successor = successor.left | |||||
current.value.value = successor.value.value | |||||
current = successor | |||||
if current.left: | |||||
child = current.left | |||||
else: | |||||
child = current.right | |||||
if not parent: | |||||
self.root = child | |||||
return child, None | |||||
elif parent.left == current: | |||||
parent.left = child | |||||
return child, parent | |||||
else: | |||||
parent.right = child | |||||
return child, parent | |||||
def walk(self): # in-order | |||||
print("[ ", end="") | |||||
self.walk_recursive(self.root, 0, 0) | |||||
print(" ]") | |||||
def graph_walk(self): | |||||
self.leaf_counter = 0 | |||||
with open("../../graph.gv", "w") as file: | |||||
file.write("digraph BST {\n") | |||||
file.write(" node [fontname=\"Arial\"];\n") | |||||
self.graph_walk_recursive(self.root, file) | |||||
file.write("}") | |||||
def graph_walk_recursive(self, current, file): | |||||
if current is not None: | |||||
if current.left: | |||||
file.write(f"{current.value} -> {current.left.value}; \n") | |||||
self.graph_walk_recursive(current.left, file) | |||||
else: | |||||
file.write(f"left{self.leaf_counter} [shape=point]; \n") | |||||
file.write(f"{current.value} -> left{self.leaf_counter}; \n") | |||||
self.leaf_counter += 1 | |||||
if current.right: | |||||
file.write(f"{current.value} -> {current.right.value}; \n") | |||||
self.graph_walk_recursive(current.right, file) | |||||
else: | |||||
file.write(f"right{self.leaf_counter} [shape=point]; \n") | |||||
file.write(f"{current.value} -> right{self.leaf_counter}; \n") | |||||
self.leaf_counter += 1 | |||||
def tree_walk(self): | |||||
self.walk_recursive(self.root, 0, 1) | |||||
def walk_recursive(self, node: BinTreeNode, level = 0, increase = 1): | |||||
if node: | |||||
if increase >= 1: | |||||
end = "\n" | |||||
else: | |||||
end = " " | |||||
self.walk_recursive(node.left, level+increase, increase) | |||||
print(" "*level*3 + str(node.value), end=end) | |||||
self.walk_recursive(node.right, level+increase, increase) | |||||
def levelwalk(self): | |||||
if self.root is None: | |||||
return | |||||
queue = [self.root] | |||||
while queue: | |||||
current = queue.pop(0) | |||||
print(current.value, end=" ") | |||||
if current.left: | |||||
queue.append(current.left) | |||||
if current.right: | |||||
queue.append(current.right) | |||||
print() | |||||
if __name__ == "__main__": | |||||
z = read_int_sequence("../../seq0.txt") | |||||
print(z, len(z)) | |||||
start = pfc() | |||||
tree = BinTree() | |||||
for i in z: | |||||
tree.insert(i) | |||||
tree.walk() | |||||
tree.tree_walk() | |||||
tree.levelwalk() | |||||
tree.delete(AlgoDatValue(46)) | |||||
tree.graph_walk() | |||||
print(f"Dauer: {pfc() - start:.4f}s") | |||||
AlgoDatValue.summary() |
from SoSe24.algodat.foundation import AlgoDatArray, AlgoDatValue, read_int_sequence, read_int_sequence_limited | |||||
import matplotlib | |||||
matplotlib.use('TkAgg') | |||||
import matplotlib.pyplot as plt | |||||
import bin_tree as bt | |||||
if __name__ == "__main__": | |||||
filename = "../../seq3_sorted.txt" | |||||
#filename = "../../seq3.txt" | |||||
dummy = read_int_sequence(filename) | |||||
n = len(dummy) | |||||
step = n // 100 | |||||
memory_values = [] | |||||
compare_values = [] | |||||
for right_end in range(1, n, step): | |||||
AlgoDatValue.reset() | |||||
z = read_int_sequence_limited(filename, right_end) | |||||
tree = bt.BinTree() | |||||
for i in z: | |||||
tree.insert(i) | |||||
memory_values.append(AlgoDatValue.memory) | |||||
compare_values.append(AlgoDatValue.compare) | |||||
print(right_end, AlgoDatValue.compare) | |||||
plt.plot(range(1, n, step), memory_values, 'b', label='Memory') | |||||
plt.plot(range(1, n, step), compare_values, 'r', label='Compare') | |||||
plt.legend() | |||||
plt.show() |
from SoSe24.algodat.foundation import AlgoDatArray, AlgoDatValue, read_int_sequence, MinusInf | |||||
from time import perf_counter as pfc | |||||
#Goldener Schnitt | |||||
import math | |||||
a = (math.sqrt(5) - 1) / 2 | |||||
def h(x, m): | |||||
return int(x*a - int(x*a) * m) | |||||
def f(x, i, m): | |||||
return (h(x, m) + i + 14*i*i) % m | |||||
def f1(x, i, m): | |||||
if i % 2 == 0: | |||||
return (h(x, m) + i*i) % m | |||||
return ((h(x, m) - i*i) % m + m) % m | |||||
class HashTable: | |||||
def __init__(self, m, h, f=None): | |||||
self.m = m | |||||
self.h = h | |||||
self.f = f | |||||
self.table = AlgoDatArray(m) | |||||
def insert(self, x): | |||||
i = 0 | |||||
while i < self.m: | |||||
j = self.f(x.value, i, self.m) | |||||
if self.is_free(j): | |||||
self.table[j].value = x.value | |||||
return True | |||||
i += 1 | |||||
return False | |||||
def search(self, x): | |||||
i = 0 | |||||
while i < self.m: | |||||
j = f(x, i, self.m) | |||||
if self.table[j] == x: | |||||
return True | |||||
if self.table[j] == None: | |||||
return False | |||||
i += 1 | |||||
return False | |||||
def delete(self, x): | |||||
i = 0 | |||||
while i < self.m: | |||||
j = f(x, i, self.m) | |||||
if self.table[j].value == x: | |||||
self.table[j].value = "DELETED" | |||||
return True | |||||
if self.table[j].value is None: | |||||
return False | |||||
i += 1 | |||||
return False | |||||
def __str__(self): | |||||
return str(self.table) | |||||
def alpha(self): | |||||
i=0 | |||||
used = 0 | |||||
while i < self.m: | |||||
used += 0 if self.is_free(i) else 1 | |||||
i += 1 | |||||
return used / self.m | |||||
def is_free(self, i): | |||||
if self.table[i] == None: | |||||
return True | |||||
if self.table[i] == "DELETED": | |||||
return True | |||||
return False | |||||
if __name__ == "__main__": | |||||
z = read_int_sequence("../../seq1.txt") | |||||
start = pfc() | |||||
hash = HashTable(31, h, f) | |||||
for i in z: | |||||
hash.insert(i) | |||||
print(hash) | |||||
print(f"Alpha: {hash.alpha()}") | |||||
hash.delete(34) | |||||
hash.search(47) | |||||
hash.search(243) | |||||
print(hash) | |||||
print(f"Alpha: {hash.alpha()}") | |||||
print(f"Dauer: {pfc() - start:.4f}s") | |||||
AlgoDatValue.summary() |
from collections import deque | |||||
from typing import List | |||||
import re | |||||
from enum import Enum | |||||
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 | |||||
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): | |||||
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 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 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 | |||||
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): | |||||
adjacency_list = self.adjacency_map[name1] | |||||
dest = self.vertex_map[name2] | |||||
adjacency_list.append(dest) | |||||
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 self.adjacency_map[name] | |||||
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(0) | |||||
self.adjacency_matrix.append([0] * len(self.vertex_list)) # add a new row | |||||
def connect(self, name1: str, name2: str): | |||||
index1 = self.index_map[name1] | |||||
index2 = self.index_map[name2] | |||||
self.adjacency_matrix[index1][index2] = 1 | |||||
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] == 1: | |||||
name = self.vertex_list[i].value | |||||
result.append(self.get_vertex(name)) | |||||
return result | |||||
def read_cave_into_graph(graph: Graph, filename: str): | |||||
"""Read a cave description from a file and insert it into the given graph.""" | |||||
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) | |||||
if __name__ == "__main__": | |||||
graph = AdjacencyListGraph() | |||||
#graph = AdjacencyMatrixGraph() | |||||
read_cave_into_graph(graph, "../../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) |