diff --git a/code/python/src/algorithms/hirschberg/algorithms.py b/code/python/src/algorithms/hirschberg/algorithms.py index f347198..06fd1b4 100644 --- a/code/python/src/algorithms/hirschberg/algorithms.py +++ b/code/python/src/algorithms/hirschberg/algorithms.py @@ -31,7 +31,7 @@ __all__ = [ def simple_algorithm( X: str, Y: str, - verb: List[EnumHirschbergVerbosity] = [], + verbose: List[EnumHirschbergVerbosity] = [], show: List[EnumHirschbergShow] = [], ) -> Tuple[str, str]: ''' @@ -41,8 +41,8 @@ def simple_algorithm( Costs, Moves = compute_cost_matrix(X = '-' + X, Y = '-' + Y); 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); - if verb != []: - repr = display_cost_matrix(Costs=Costs, path=path, X = '-' + X, Y = '-' + Y, verb=verb); + if verbose != []: + repr = display_cost_matrix(Costs=Costs, path=path, X = '-' + X, Y = '-' + Y, verbose=verbose); 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'); return word_x, word_y; @@ -51,7 +51,7 @@ def hirschberg_algorithm( X: str, Y: str, once: bool = False, - verb: List[EnumHirschbergVerbosity] = [], + verbose: List[EnumHirschbergVerbosity] = [], show: List[EnumHirschbergShow] = [], ) -> Tuple[str, str]: ''' @@ -66,14 +66,14 @@ def hirschberg_algorithm( ''' # ggf. nur den simplen Algorithmus ausführen: if once: - return simple_algorithm(X=X, Y=Y, verb=verb, show=show); + return simple_algorithm(X=X, Y=Y, verbose=verbose, show=show); - align = hirschberg_algorithm_step(X=X, Y=Y, depth=1, verb=verb, show=show); + align = hirschberg_algorithm_step(X=X, Y=Y, depth=1, verbose=verbose, show=show); word_x = align.as_string1(); word_y = align.as_string2(); # verbose output hier behandeln (irrelevant für Algorithmus): - if verb != []: + if verbose != []: if EnumHirschbergShow.tree in show: display = align.astree(braces=True); else: @@ -88,7 +88,7 @@ def hirschberg_algorithm_step( X: str, Y: str, depth: int = 0, - verb: List[EnumHirschbergVerbosity] = [], + verbose: List[EnumHirschbergVerbosity] = [], show: List[EnumHirschbergShow] = [], ) -> 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); # verbose output hier behandeln (irrelevant für Algorithmus): - if verb != [] and (EnumHirschbergShow.atoms in show): - repr = display_cost_matrix(Costs=Costs, path=path, X = '-' + X, Y = '-' + Y, verb=verb); + if verbose != [] and (EnumHirschbergShow.atoms in show): + repr = display_cost_matrix(Costs=Costs, path=path, X = '-' + X, Y = '-' + Y, verbose=verbose); print(f'\n\x1b[1mRekursionstiefe: {depth}\x1b[0m\n\n{repr}') 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); # verbose output hier behandeln (irrelevant für Algorithmus): - if verb != []: + if verbose != []: path1, path2 = reconstruct_optimal_path_halves(Costs1=Costs1, Costs2=Costs2, Moves1=Moves1, Moves2=Moves2); repr = display_cost_matrix_halves( Costs1 = Costs1, @@ -138,7 +138,7 @@ def hirschberg_algorithm_step( X2 = '-' + X2, Y1 = '-' + Y1, Y2 = '-' + Y2, - verb = verb, + verbose = verbose, ); 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); p = coord1[0]; # Divide and Conquer ausführen: - 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, verb=verb, show=show); + align_left = 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, verbose=verbose, show=show); # Resultate zusammensetzen: return AlignmentPair(left=align_left, right=align_right); diff --git a/code/python/src/algorithms/hirschberg/display.py b/code/python/src/algorithms/hirschberg/display.py index 4bcd6c6..c8d3f77 100644 --- a/code/python/src/algorithms/hirschberg/display.py +++ b/code/python/src/algorithms/hirschberg/display.py @@ -30,7 +30,7 @@ def represent_cost_matrix( path: List[Tuple[int, int]], X: str, Y: str, - verb: List[EnumHirschbergVerbosity], + verbose: List[EnumHirschbergVerbosity], pad: bool = False, ) -> np.ndarray: # NDArray[(Any, Any), Any]: m = len(X); # display vertically @@ -55,12 +55,12 @@ def represent_cost_matrix( table[-3, 3:(3+n)] = '--'; table[3:(3+m), -1] = '|'; - if EnumHirschbergVerbosity.costs in verb: + if EnumHirschbergVerbosity.costs in verbose: table[3:(3+m), 3:(3+n)] = Costs.copy(); - if EnumHirschbergVerbosity.moves in verb: + if EnumHirschbergVerbosity.moves in verbose: for (i, j) in path: table[3 + i, 3 + j] = f'\x1b[31;4;1m{table[3 + i, 3 + j]}\x1b[0m'; - elif EnumHirschbergVerbosity.moves in verb: + elif EnumHirschbergVerbosity.moves in verbose: table[3:(3+m), 3:(3+n)] = '\x1b[2m.\x1b[0m'; for (i, j) in path: table[3 + i, 3 + j] = '\x1b[31;1m*\x1b[0m'; @@ -72,7 +72,7 @@ def display_cost_matrix( path: List[Tuple[int, int]], X: str, Y: str, - verb: EnumHirschbergVerbosity, + verbose: EnumHirschbergVerbosity, ) -> str: ''' Zeigt Kostenmatrix + optimalen Pfad. @@ -85,7 +85,7 @@ def display_cost_matrix( @returns - eine 'printable' Darstellung der Matrix mit den Strings X, Y + Indexes. ''' - table = represent_cost_matrix(Costs=Costs, path=path, X=X, Y=Y, verb=verb); + table = represent_cost_matrix(Costs=Costs, path=path, X=X, Y=Y, verbose=verbose); # benutze pandas-Dataframe + tabulate, um schöner darzustellen: repr = tabulate(pd.DataFrame(table), showindex=False, stralign='center', tablefmt='plain'); return repr; @@ -99,7 +99,7 @@ def display_cost_matrix_halves( X2: str, Y1: str, Y2: str, - verb: EnumHirschbergVerbosity, + verbose: EnumHirschbergVerbosity, ) -> str: ''' Zeigt Kostenmatrix + optimalen Pfad für Schritt im D & C Hirschberg-Algorithmus @@ -112,8 +112,8 @@ def display_cost_matrix_halves( @returns - eine 'printable' Darstellung der Matrix mit den Strings X, Y + Indexes. ''' - 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, verb=verb, pad=True); + table1 = represent_cost_matrix(Costs=Costs1, path=path1, X=X1, Y=Y1, verbose=verbose, pad=True); + table2 = represent_cost_matrix(Costs=Costs2, path=path2, X=X2, Y=Y2, verbose=verbose, pad=True); # merge Taellen: table = np.concatenate([table1[:, :-1], table2[::-1, ::-1]], axis=1); diff --git a/code/python/src/algorithms/tarjan/algorithms.py b/code/python/src/algorithms/tarjan/algorithms.py index ebdbe92..a29233b 100644 --- a/code/python/src/algorithms/tarjan/algorithms.py +++ b/code/python/src/algorithms/tarjan/algorithms.py @@ -34,18 +34,22 @@ class State(Enum): # Tarjan Algorithm # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -def tarjan_algorithm(G: Graph, debug: bool = False) -> List[Any]: +def tarjan_algorithm(G: Graph, verbose: bool = False) -> List[Any]: ''' # Tarjan Algorithm # Runs the Tarjan-Algorithm to compute the strongly connected components. ''' # initialise state - mark all nodes as UNTOUCHED: - ctx = Context(G, debug=debug); + ctx = Context(G, verbose=verbose); # loop through all nodes and carry out Tarjan-Algorithm, provided node not already visitted. for u in G.nodes: if ctx.get_state(u) == State.UNTOUCHED: tarjan_visit(G, u, ctx); + if verbose: + for component in ctx.components: + log_debug(component); + return ctx.components; def tarjan_visit(G: Graph, u: Any, ctx: Context): @@ -107,15 +111,15 @@ class NodeInformation(NodeInformationDefault): @dataclass class ContextDefault: max_index: int = field(default=0); - debug: bool = field(default=False); + verbose: bool = field(default=False); stack: Stack = field(default_factory=lambda: Stack()); components: list[list[Any]] = field(default_factory=lambda: []); infos: dict[Any, NodeInformation] = field(default_factory=lambda: dict()); class Context(ContextDefault): - def __init__(self, G: Graph, debug: bool): + def __init__(self, G: Graph, verbose: bool): super().__init__(); - self.debug = debug; + self.verbose = verbose; self.infos = { u: NodeInformation(u) for u in G.nodes }; def push(self, u: Any): @@ -161,7 +165,7 @@ class Context(ContextDefault): return self.get_info(u).index; def log_info(self, u: Any): - if not self.debug: + if not self.verbose: return; info = self.get_info(u); log_debug(info);