Compare commits

..

No commits in common. "c0bc69450ce51b45c738ddc9acc8783d520539b6" and "6920944cdfc6b157d70fb23e69759a20b89c41d4" have entirely different histories.

9 changed files with 42 additions and 124 deletions

View File

@ -1,37 +1,12 @@
## Beispiele für Seminarwoche 2 (Blatt 1) ## Beispiel für Seminarwoche 9 (Blatt 8)
- name: TARJAN
nodes: [a,b,c]
edges: [[a, c], [c, a], [b, c]]
- name: TARJAN
nodes: [1, 2, 3, 4, 5, 6, 7, 8]
edges: [
[1, 2],
[1, 3],
[2, 4],
[2, 5],
[3, 5],
[3, 6],
[3, 8],
[4, 5],
[4, 7],
[5, 1],
[5, 8],
[6, 8],
[7, 8],
[8, 6],
]
## Beispiele für Seminarwoche 9 (Blatt 8)
- name: TSP - name: TSP
dist: &ref_dist [ dist: [
[0, 7, 4, 3], [0, 7, 4, 3],
[7, 0, 5, 6], [7, 0, 5, 6],
[2, 5, 0, 5], [2, 5, 0, 5],
[2, 7, 4, 0], [2, 7, 4, 0],
] ]
optimise: MIN optimise: MIN
- name: TSP
dist: *ref_dist
optimise: MAX
# Beispiele für Seminarwoche 10 (Blatt 9) # Beispiele für Seminarwoche 10 (Blatt 9)
- name: HIRSCHBERG - name: HIRSCHBERG
word1: 'happily ever after' word1: 'happily ever after'

View File

@ -6,8 +6,6 @@ info:
ADS2 an der Universität Leipzig (Sommersemester 2022) ADS2 an der Universität Leipzig (Sommersemester 2022)
implementiert. implementiert.
options: options:
tarjan:
verbose: true
tsp: tsp:
verbose: true verbose: true
hirschberg: hirschberg:

View File

@ -17,8 +17,8 @@ from models.generated.config import *;
from models.generated.commands import *; from models.generated.commands import *;
from src.core.log import *; from src.core.log import *;
from src.setup.config import *; from src.setup.config import *;
from src.models.graphs import *; from src.models.graphs.graph import *;
from src.algorithms.tarjan import *; from src.algorithms.tarjan.algorithms import *;
from src.algorithms.tsp import *; from src.algorithms.tsp import *;
from src.algorithms.hirschberg import *; from src.algorithms.hirschberg import *;
@ -34,14 +34,6 @@ from src.algorithms.hirschberg import *;
def enter(): def enter():
for command in COMMANDS: for command in COMMANDS:
if isinstance(command, CommandTarjan):
tarjan_algorithm(
G = Graph(
nodes=command.nodes,
edges=list(map(tuple, command.edges)),
),
verbose = OPTIONS.tarjan.verbose
);
if isinstance(command, CommandTsp): if isinstance(command, CommandTsp):
tsp_algorithm( tsp_algorithm(
dist = np.asarray(command.dist, dtype=float), dist = np.asarray(command.dist, dtype=float),
@ -53,7 +45,7 @@ def enter():
X = command.word1, X = command.word1,
Y = command.word2, Y = command.word2,
once = command.once, once = command.once,
verbose = OPTIONS.hirschberg.verbose, verb = OPTIONS.hirschberg.verbose,
show = OPTIONS.hirschberg.show, show = OPTIONS.hirschberg.show,
); );
return; return;

View File

@ -37,19 +37,10 @@ components:
type: object type: object
required: required:
- name - name
- nodes
- edges
properties: properties:
<<: *ref_command_properties <<: *ref_command_properties
nodes: # required:
type: array # properties:
edges:
type: array
items:
# $ref: '#/components/schemas/Edge'
type: array
minItems: 2
maxItems: 2
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Command - Algorithm: TSP # Command - Algorithm: TSP
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -51,14 +51,6 @@ components:
- tsp - tsp
- hirschberg - hirschberg
properties: properties:
tarjan:
type: object
required:
- verbose
properties:
verbose:
type: boolean
default: false
tsp: tsp:
type: object type: object
required: required:

View File

@ -31,7 +31,7 @@ __all__ = [
def simple_algorithm( def simple_algorithm(
X: str, X: str,
Y: str, Y: str,
verbose: List[EnumHirschbergVerbosity] = [], verb: List[EnumHirschbergVerbosity] = [],
show: List[EnumHirschbergShow] = [], show: List[EnumHirschbergShow] = [],
) -> Tuple[str, str]: ) -> Tuple[str, str]:
''' '''
@ -41,8 +41,8 @@ def simple_algorithm(
Costs, Moves = compute_cost_matrix(X = '-' + X, Y = '-' + Y); Costs, Moves = compute_cost_matrix(X = '-' + X, Y = '-' + Y);
path = reconstruct_optimal_path(Moves=Moves); path = reconstruct_optimal_path(Moves=Moves);
word_x, word_y = reconstruct_words(X = '-' + X, Y = '-' + Y, moves=[Moves[coord] for coord in path], path=path); word_x, word_y = reconstruct_words(X = '-' + X, Y = '-' + Y, moves=[Moves[coord] for coord in path], path=path);
if verbose != []: if verb != []:
repr = display_cost_matrix(Costs=Costs, path=path, X = '-' + X, Y = '-' + Y, verbose=verbose); repr = display_cost_matrix(Costs=Costs, path=path, X = '-' + X, Y = '-' + Y, verb=verb);
display = word_y + f'\n{"-"*len(word_x)}\n' + word_x; display = word_y + f'\n{"-"*len(word_x)}\n' + word_x;
print(f'\n{repr}\n\n\x1b[1mOptimales Alignment:\x1b[0m\n\n{display}\n'); print(f'\n{repr}\n\n\x1b[1mOptimales Alignment:\x1b[0m\n\n{display}\n');
return word_x, word_y; return word_x, word_y;
@ -51,7 +51,7 @@ def hirschberg_algorithm(
X: str, X: str,
Y: str, Y: str,
once: bool = False, once: bool = False,
verbose: List[EnumHirschbergVerbosity] = [], verb: List[EnumHirschbergVerbosity] = [],
show: List[EnumHirschbergShow] = [], show: List[EnumHirschbergShow] = [],
) -> Tuple[str, str]: ) -> Tuple[str, str]:
''' '''
@ -66,14 +66,14 @@ def hirschberg_algorithm(
''' '''
# ggf. nur den simplen Algorithmus ausführen: # ggf. nur den simplen Algorithmus ausführen:
if once: if once:
return simple_algorithm(X=X, Y=Y, verbose=verbose, show=show); return simple_algorithm(X=X, Y=Y, verb=verb, show=show);
align = hirschberg_algorithm_step(X=X, Y=Y, depth=1, verbose=verbose, show=show); align = hirschberg_algorithm_step(X=X, Y=Y, depth=1, verb=verb, show=show);
word_x = align.as_string1(); word_x = align.as_string1();
word_y = align.as_string2(); word_y = align.as_string2();
# verbose output hier behandeln (irrelevant für Algorithmus): # verbose output hier behandeln (irrelevant für Algorithmus):
if verbose != []: if verb != []:
if EnumHirschbergShow.tree in show: if EnumHirschbergShow.tree in show:
display = align.astree(braces=True); display = align.astree(braces=True);
else: else:
@ -88,7 +88,7 @@ def hirschberg_algorithm_step(
X: str, X: str,
Y: str, Y: str,
depth: int = 0, depth: int = 0,
verbose: List[EnumHirschbergVerbosity] = [], verb: List[EnumHirschbergVerbosity] = [],
show: List[EnumHirschbergShow] = [], show: List[EnumHirschbergShow] = [],
) -> Alignment: ) -> Alignment:
''' '''
@ -106,8 +106,8 @@ def hirschberg_algorithm_step(
word_x, word_y = reconstruct_words(X = '-' + X, Y = '-' + Y, moves=[Moves[coord] for coord in path], path=path); word_x, word_y = reconstruct_words(X = '-' + X, Y = '-' + Y, moves=[Moves[coord] for coord in path], path=path);
# verbose output hier behandeln (irrelevant für Algorithmus): # verbose output hier behandeln (irrelevant für Algorithmus):
if verbose != [] and (EnumHirschbergShow.atoms in show): if verb != [] and (EnumHirschbergShow.atoms in show):
repr = display_cost_matrix(Costs=Costs, path=path, X = '-' + X, Y = '-' + Y, verbose=verbose); repr = display_cost_matrix(Costs=Costs, path=path, X = '-' + X, Y = '-' + Y, verb=verb);
print(f'\n\x1b[1mRekursionstiefe: {depth}\x1b[0m\n\n{repr}') print(f'\n\x1b[1mRekursionstiefe: {depth}\x1b[0m\n\n{repr}')
return AlignmentBasic(word1=word_x, word2=word_y); return AlignmentBasic(word1=word_x, word2=word_y);
@ -127,7 +127,7 @@ def hirschberg_algorithm_step(
Costs2, Moves2 = compute_cost_matrix(X = '-' + X2, Y = '-' + Y2); Costs2, Moves2 = compute_cost_matrix(X = '-' + X2, Y = '-' + Y2);
# verbose output hier behandeln (irrelevant für Algorithmus): # verbose output hier behandeln (irrelevant für Algorithmus):
if verbose != []: if verb != []:
path1, path2 = reconstruct_optimal_path_halves(Costs1=Costs1, Costs2=Costs2, Moves1=Moves1, Moves2=Moves2); path1, path2 = reconstruct_optimal_path_halves(Costs1=Costs1, Costs2=Costs2, Moves1=Moves1, Moves2=Moves2);
repr = display_cost_matrix_halves( repr = display_cost_matrix_halves(
Costs1 = Costs1, Costs1 = Costs1,
@ -138,7 +138,7 @@ def hirschberg_algorithm_step(
X2 = '-' + X2, X2 = '-' + X2,
Y1 = '-' + Y1, Y1 = '-' + Y1,
Y2 = '-' + Y2, Y2 = '-' + Y2,
verbose = verbose, verb = verb,
); );
print(f'\n\x1b[1mRekursionstiefe: {depth}\x1b[0m\n\n{repr}') print(f'\n\x1b[1mRekursionstiefe: {depth}\x1b[0m\n\n{repr}')
@ -146,8 +146,8 @@ def hirschberg_algorithm_step(
coord1, coord2 = get_optimal_transition(Costs1=Costs1, Costs2=Costs2); coord1, coord2 = get_optimal_transition(Costs1=Costs1, Costs2=Costs2);
p = coord1[0]; p = coord1[0];
# Divide and Conquer ausführen: # Divide and Conquer ausführen:
align_left = hirschberg_algorithm_step(X=X[:p], Y=Y[:n], depth=depth+1, verbose=verbose, show=show); align_left = hirschberg_algorithm_step(X=X[:p], Y=Y[:n], depth=depth+1, verb=verb, show=show);
align_right = hirschberg_algorithm_step(X=X[p:], Y=Y[n:], depth=depth+1, verbose=verbose, show=show); align_right = hirschberg_algorithm_step(X=X[p:], Y=Y[n:], depth=depth+1, verb=verb, show=show);
# Resultate zusammensetzen: # Resultate zusammensetzen:
return AlignmentPair(left=align_left, right=align_right); return AlignmentPair(left=align_left, right=align_right);

View File

@ -30,7 +30,7 @@ def represent_cost_matrix(
path: List[Tuple[int, int]], path: List[Tuple[int, int]],
X: str, X: str,
Y: str, Y: str,
verbose: List[EnumHirschbergVerbosity], verb: List[EnumHirschbergVerbosity],
pad: bool = False, pad: bool = False,
) -> np.ndarray: # NDArray[(Any, Any), Any]: ) -> np.ndarray: # NDArray[(Any, Any), Any]:
m = len(X); # display vertically m = len(X); # display vertically
@ -55,12 +55,12 @@ def represent_cost_matrix(
table[-3, 3:(3+n)] = '--'; table[-3, 3:(3+n)] = '--';
table[3:(3+m), -1] = '|'; table[3:(3+m), -1] = '|';
if EnumHirschbergVerbosity.costs in verbose: if EnumHirschbergVerbosity.costs in verb:
table[3:(3+m), 3:(3+n)] = Costs.copy(); table[3:(3+m), 3:(3+n)] = Costs.copy();
if EnumHirschbergVerbosity.moves in verbose: if EnumHirschbergVerbosity.moves in verb:
for (i, j) in path: for (i, j) in path:
table[3 + i, 3 + j] = f'\x1b[31;4;1m{table[3 + i, 3 + j]}\x1b[0m'; table[3 + i, 3 + j] = f'\x1b[31;4;1m{table[3 + i, 3 + j]}\x1b[0m';
elif EnumHirschbergVerbosity.moves in verbose: elif EnumHirschbergVerbosity.moves in verb:
table[3:(3+m), 3:(3+n)] = '\x1b[2m.\x1b[0m'; table[3:(3+m), 3:(3+n)] = '\x1b[2m.\x1b[0m';
for (i, j) in path: for (i, j) in path:
table[3 + i, 3 + j] = '\x1b[31;1m*\x1b[0m'; table[3 + i, 3 + j] = '\x1b[31;1m*\x1b[0m';
@ -72,7 +72,7 @@ def display_cost_matrix(
path: List[Tuple[int, int]], path: List[Tuple[int, int]],
X: str, X: str,
Y: str, Y: str,
verbose: EnumHirschbergVerbosity, verb: EnumHirschbergVerbosity,
) -> str: ) -> str:
''' '''
Zeigt Kostenmatrix + optimalen Pfad. Zeigt Kostenmatrix + optimalen Pfad.
@ -85,7 +85,7 @@ def display_cost_matrix(
@returns @returns
- eine 'printable' Darstellung der Matrix mit den Strings X, Y + Indexes. - eine 'printable' Darstellung der Matrix mit den Strings X, Y + Indexes.
''' '''
table = represent_cost_matrix(Costs=Costs, path=path, X=X, Y=Y, verbose=verbose); table = represent_cost_matrix(Costs=Costs, path=path, X=X, Y=Y, verb=verb);
# benutze pandas-Dataframe + tabulate, um schöner darzustellen: # benutze pandas-Dataframe + tabulate, um schöner darzustellen:
repr = tabulate(pd.DataFrame(table), showindex=False, stralign='center', tablefmt='plain'); repr = tabulate(pd.DataFrame(table), showindex=False, stralign='center', tablefmt='plain');
return repr; return repr;
@ -99,7 +99,7 @@ def display_cost_matrix_halves(
X2: str, X2: str,
Y1: str, Y1: str,
Y2: str, Y2: str,
verbose: EnumHirschbergVerbosity, verb: EnumHirschbergVerbosity,
) -> str: ) -> str:
''' '''
Zeigt Kostenmatrix + optimalen Pfad für Schritt im D & C Hirschberg-Algorithmus Zeigt Kostenmatrix + optimalen Pfad für Schritt im D & C Hirschberg-Algorithmus
@ -112,8 +112,8 @@ def display_cost_matrix_halves(
@returns @returns
- eine 'printable' Darstellung der Matrix mit den Strings X, Y + Indexes. - eine 'printable' Darstellung der Matrix mit den Strings X, Y + Indexes.
''' '''
table1 = represent_cost_matrix(Costs=Costs1, path=path1, X=X1, Y=Y1, verbose=verbose, pad=True); table1 = represent_cost_matrix(Costs=Costs1, path=path1, X=X1, Y=Y1, verb=verb, pad=True);
table2 = represent_cost_matrix(Costs=Costs2, path=path2, X=X2, Y=Y2, verbose=verbose, pad=True); table2 = represent_cost_matrix(Costs=Costs2, path=path2, X=X2, Y=Y2, verb=verb, pad=True);
# merge Taellen: # merge Taellen:
table = np.concatenate([table1[:, :-1], table2[::-1, ::-1]], axis=1); table = np.concatenate([table1[:, :-1], table2[::-1, ::-1]], axis=1);

View File

@ -8,7 +8,6 @@
from __future__ import annotations; from __future__ import annotations;
from src.thirdparty.types import *; from src.thirdparty.types import *;
from src.thirdparty.maths import *;
from src.core.log import *; from src.core.log import *;
from src.models.stacks import *; from src.models.stacks import *;
@ -35,31 +34,18 @@ class State(Enum):
# Tarjan Algorithm # Tarjan Algorithm
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def tarjan_algorithm(G: Graph, verbose: bool = False) -> List[Any]: def tarjan_algorithm(G: Graph, debug: bool = False) -> List[Any]:
''' '''
# Tarjan Algorithm # # Tarjan Algorithm #
Runs the Tarjan-Algorithm to compute the strongly connected components. Runs the Tarjan-Algorithm to compute the strongly connected components.
''' '''
# initialise state - mark all nodes as UNTOUCHED: # initialise state - mark all nodes as UNTOUCHED:
ctx = Context(G); ctx = Context(G, debug=debug);
# loop through all nodes and carry out Tarjan-Algorithm, provided node not already visitted. # loop through all nodes and carry out Tarjan-Algorithm, provided node not already visitted.
for u in G.nodes: for u in G.nodes:
if ctx.get_state(u) == State.UNTOUCHED: if ctx.get_state(u) == State.UNTOUCHED:
tarjan_visit(G, u, ctx); tarjan_visit(G, u, ctx);
if verbose:
repr = ctx.repr();
print('');
print(f'\x1b[1mZusammenfassung der Ausführung des Tarjan-Algorithmus\x1b[0m');
print('');
print(repr);
print('');
print('\x1b[1mStark zshgd Komponenten:\x1b[0m')
print('');
for component in ctx.components:
print(component);
print('');
return ctx.components; return ctx.components;
def tarjan_visit(G: Graph, u: Any, ctx: Context): def tarjan_visit(G: Graph, u: Any, ctx: Context):
@ -121,15 +107,15 @@ class NodeInformation(NodeInformationDefault):
@dataclass @dataclass
class ContextDefault: class ContextDefault:
max_index: int = field(default=0); max_index: int = field(default=0);
verbose: bool = field(default=False); debug: bool = field(default=False);
stack: Stack = field(default_factory=lambda: Stack()); stack: Stack = field(default_factory=lambda: Stack());
components: list[list[Any]] = field(default_factory=list); components: list[list[Any]] = field(default_factory=lambda: []);
infos: dict[Any, NodeInformation] = field(default_factory=dict); infos: dict[Any, NodeInformation] = field(default_factory=lambda: dict());
finished: List[Any] = field(default_factory=list);
class Context(ContextDefault): class Context(ContextDefault):
def __init__(self, G: Graph): def __init__(self, G: Graph, debug: bool):
super().__init__(); super().__init__();
self.debug = debug;
self.infos = { u: NodeInformation(u) for u in G.nodes }; self.infos = { u: NodeInformation(u) for u in G.nodes };
def push(self, u: Any): def push(self, u: Any):
@ -175,21 +161,7 @@ class Context(ContextDefault):
return self.get_info(u).index; return self.get_info(u).index;
def log_info(self, u: Any): def log_info(self, u: Any):
self.finished.append(u); if not self.debug:
return;
def repr(self) -> str: info = self.get_info(u);
table = pd.DataFrame([ self.infos[u] for u in self.finished ]) \ log_debug(info);
.drop(columns='state')
# benutze pandas-Dataframe + tabulate, um schöner darzustellen:
repr = tabulate(
table,
headers = {
'Knoten': 'node',
'kleinster Idx': 'least_index',
'Index': 'index',
},
showindex = False,
stralign = 'center',
tablefmt = 'grid',
);
return repr;

View File

@ -7,7 +7,6 @@
from __future__ import annotations; from __future__ import annotations;
from models.generated.commands import *;
from src.thirdparty.types import *; from src.thirdparty.types import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -29,8 +28,7 @@ class Graph(object):
nodes: list[Any]; nodes: list[Any];
edges: list[tuple[Any,Any]] edges: list[tuple[Any,Any]]
def __init__(self, nodes: list[Any], edges: list[Tuple[Any, Any]]): def __init__(self, nodes: list[Any], edges: list[tuple[Any,Any]]):
assert all(len(edge) == 2 for edge in edges);
self.nodes = nodes; self.nodes = nodes;
self.edges = edges; self.edges = edges;
return; return;