forked from hofmannol/AlgoDatSoSe25
Compare commits
No commits in common. "50444c6f7a3af0695b296ee6b282b21b1366b9cf" and "a6aeff66cd278a967fc44c04d8cfdbe0c35769c5" have entirely different histories.
50444c6f7a
...
a6aeff66cd
@ -1,25 +0,0 @@
|
|||||||
"Höhleneingang" <> "Ost/West-Passage"
|
|
||||||
"Höhleneingang" <> "Nord/Süd-Passage"
|
|
||||||
"Nord/Süd-Passage" <> "Nebelraum"
|
|
||||||
"Steiniger Pfad" > "Ost/West-Passage"
|
|
||||||
"Ost/West-Passage" <> "Schwefelgewölbe"
|
|
||||||
"Schwefelgewölbe" > "Steiniger Pfad"
|
|
||||||
"Schatzkammer" > "Nebelraum"
|
|
||||||
"Steiniger Pfad" <> "Schatzkammer"
|
|
||||||
"Steiniger Pfad" > "Höhleneingang"
|
|
||||||
"Kristallhöhle" <> "Schwefelgewölbe"
|
|
||||||
"Kristallhöhle" <> "Nebelraum"
|
|
||||||
"Versteckter Gang" > "Kristallhöhle"
|
|
||||||
"Versteckter Gang" > "Schatzkammer"
|
|
||||||
"Unterirdischer See" <> "Kristallhöhle"
|
|
||||||
"Unterirdischer See" <> "Ost/West-Passage"
|
|
||||||
"Geheimgang" > "Unterirdischer See"
|
|
||||||
"Geheimgang" > "Versteckter Gang"
|
|
||||||
"Abgrund" > "Geheimgang"
|
|
||||||
"Abgrund" > "Nebelraum"
|
|
||||||
"Verlorene Kammer" > "Abgrund"
|
|
||||||
"Verlorene Kammer" > "Schwefelgewölbe"
|
|
||||||
"Geheimgang" > "Schatzkammer"
|
|
||||||
"Kristallhöhle" > "Höhleneingang"
|
|
||||||
"Schwefelgewölbe" > "Höhleneingang"
|
|
||||||
"Abgrund" > "Schatzkammer"
|
|
@ -1,124 +0,0 @@
|
|||||||
import logging
|
|
||||||
from graphviz import Digraph
|
|
||||||
from collections import deque
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
# logging.basicConfig(level=logging.DEBUG)
|
|
||||||
|
|
||||||
import time
|
|
||||||
|
|
||||||
def timeMS(func, *args, **kwargs):
|
|
||||||
startTime = time.perf_counter()
|
|
||||||
result = func(*args, **kwargs)
|
|
||||||
endTime = time.perf_counter()
|
|
||||||
elapsedMS = (endTime - startTime) * 1000 # Convert to milliseconds
|
|
||||||
print(f"{func.__name__} took {elapsedMS:.2f} ms")
|
|
||||||
return result
|
|
||||||
|
|
||||||
from utils.memory_array import MemoryArray
|
|
||||||
from utils.memory_cell import MemoryCell
|
|
||||||
from utils.literal import Literal
|
|
||||||
from utils.memory_range import mrange
|
|
||||||
from utils.memory_manager import MemoryManager
|
|
||||||
|
|
||||||
class Graph:
|
|
||||||
def __init__(self):
|
|
||||||
self.adjacencyList = {}
|
|
||||||
|
|
||||||
def addEdge(self, node1, node2, bidirectional=True):
|
|
||||||
if node1 not in self.adjacencyList:
|
|
||||||
self.adjacencyList[node1] = []
|
|
||||||
if node2 not in self.adjacencyList:
|
|
||||||
self.adjacencyList[node2] = []
|
|
||||||
self.adjacencyList[node1].append(node2)
|
|
||||||
if bidirectional:
|
|
||||||
self.adjacencyList[node2].append(node1)
|
|
||||||
|
|
||||||
def serialize(self):
|
|
||||||
return self.adjacencyList
|
|
||||||
|
|
||||||
def breadthFirstSearch(self, start, goal, edgesGonePassed = None):
|
|
||||||
if start not in self.adjacencyList or goal not in self.adjacencyList:
|
|
||||||
return None, None
|
|
||||||
|
|
||||||
# Dont want to have a class for this, set suffices
|
|
||||||
visited = set()
|
|
||||||
queue = deque([(start, [start], set())]) # (current_node, path, edgesGoneToGetHere)
|
|
||||||
|
|
||||||
while queue:
|
|
||||||
currentNode, path, edgesGone = queue.popleft()
|
|
||||||
|
|
||||||
if currentNode == goal:
|
|
||||||
return path, edgesGone
|
|
||||||
|
|
||||||
if currentNode not in visited:
|
|
||||||
logger.info(f"visiting {currentNode}")
|
|
||||||
visited.add(currentNode)
|
|
||||||
for neighbor in self.adjacencyList[currentNode]:
|
|
||||||
edge = (currentNode, neighbor)
|
|
||||||
# We already went this Edge. Read Part3 as not allowing this to happen
|
|
||||||
edgeReverse = (neighbor, currentNode)
|
|
||||||
if neighbor not in visited and (edgesGonePassed is None or edge not in edgesGonePassed) and (edgesGonePassed is None or edgeReverse not in edgesGonePassed):
|
|
||||||
# Pythonic way of saying neighbour, path no next clear neighbour
|
|
||||||
# and union of edgesGone with current edge
|
|
||||||
queue.append((neighbor, path + [neighbor], edgesGone | {edge}))
|
|
||||||
|
|
||||||
return None, None
|
|
||||||
|
|
||||||
|
|
||||||
def graphvizify(filePath: str, outputFile: str = 'build/hoehleGraph'):
|
|
||||||
graph = Digraph()
|
|
||||||
graph.attr(rankdir='TB')
|
|
||||||
graph.attr('node', shape='circle', style='filled', fillcolor='lightgray')
|
|
||||||
graph.attr('edge', arrowsize='0.7')
|
|
||||||
|
|
||||||
# Reuse the function to also create our Graph... Waste not want not^^
|
|
||||||
caveGraph = Graph();
|
|
||||||
|
|
||||||
with open(filePath, 'r') as f:
|
|
||||||
for line in f:
|
|
||||||
line = line.strip()
|
|
||||||
delimiter = '<>' if '<>' in line else '>' if '>' in line else None
|
|
||||||
if delimiter:
|
|
||||||
node1, node2 = map(str.strip, line.split(delimiter))
|
|
||||||
node1, node2 = map(lambda x: x.strip('"'), map(str.strip, line.split(delimiter)))
|
|
||||||
graph.edge(f"\"{node1}\"", f"\"{node2}\"", dir='none' if delimiter == '<>' else None)
|
|
||||||
caveGraph.addEdge(node1, node2, (delimiter == '<>'));
|
|
||||||
|
|
||||||
try:
|
|
||||||
graph.render(outputFile, view=True)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Could not display graph: {e}\n Trying to save without viewing!")
|
|
||||||
try:
|
|
||||||
graph.render(outputFile, view=False)
|
|
||||||
print(f"Your built map should be available here: {outputFile}.pdf")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Could not save graph file: {e}")
|
|
||||||
|
|
||||||
return caveGraph
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
for filename in [ "data/hoehle.txt", "data/hoehleLarger.txt"]:
|
|
||||||
caveGraph = graphvizify(filename, 'build/hoehleGraph')
|
|
||||||
|
|
||||||
start = "Höhleneingang"
|
|
||||||
goal = "Schatzkammer"
|
|
||||||
shortestPath, edgesGoneInitial = caveGraph.breadthFirstSearch(start, goal)
|
|
||||||
logger.debug(caveGraph.adjacencyList)
|
|
||||||
logger.debug(edgesGoneInitial)
|
|
||||||
|
|
||||||
if shortestPath:
|
|
||||||
print(f"Shortest path from {start} to {goal} is:")
|
|
||||||
print(" -> ".join(shortestPath))
|
|
||||||
else:
|
|
||||||
print(f"No path found from {start} to {goal}.")
|
|
||||||
|
|
||||||
returnpath, _ = caveGraph.breadthFirstSearch(goal, start, edgesGoneInitial)
|
|
||||||
|
|
||||||
if returnpath:
|
|
||||||
print(f"Shortest path from {goal} to {start} is:")
|
|
||||||
print(" -> ".join(returnpath))
|
|
||||||
else:
|
|
||||||
print("No path back Home found. Good Luck")
|
|
||||||
|
|
||||||
exit(0)
|
|
Loading…
x
Reference in New Issue
Block a user