diff --git a/code/python/src/main.py b/code/python/src/main.py index 9391c1f..87ecea2 100644 --- a/code/python/src/main.py +++ b/code/python/src/main.py @@ -52,6 +52,7 @@ def enter(): # Y = 'apple', # X = 'happily', verbose = True, + just_moves = False, ); return; diff --git a/code/python/src/string_alignment/hirschberg.py b/code/python/src/string_alignment/hirschberg.py index 2a1ee38..59eb3cf 100644 --- a/code/python/src/string_alignment/hirschberg.py +++ b/code/python/src/string_alignment/hirschberg.py @@ -45,14 +45,16 @@ def hirschberg_algorithm_once( X: str, Y: str, verbose: bool = False, + just_moves: bool = False, ) -> Tuple[str, str]: 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 verbose: - repr = display_cost_matrix(Costs=Costs, path=path, X = '-' + X, Y = '-' + Y); + repr = display_cost_matrix(Costs=Costs, path=path, X = '-' + X, Y = '-' + Y, just_moves=just_moves); print(f'\n{repr}'); print(f'\n\x1b[1mOptimales Alignment:\x1b[0m'); + print(''); print(word_y); print(len(word_x) * '-'); print(word_x); @@ -63,14 +65,16 @@ def hirschberg_algorithm( X: str, Y: str, verbose: bool = False, + just_moves: bool = False, ) -> Tuple[str, str]: - alignments_x, alignments_y = hirschberg_algorithm_step(X=X, Y=Y, depth=1, verbose=verbose); + alignments_x, alignments_y = hirschberg_algorithm_step(X=X, Y=Y, depth=1, verbose=verbose, just_moves=just_moves); word_x = ''.join(alignments_x); word_y = ''.join(alignments_y); if verbose: - display_x = '|'.join(alignments_x); - display_y = '|'.join(alignments_y); + display_x = f'[{"][".join(alignments_x)}]'; + display_y = f'[{"][".join(alignments_y)}]'; print(f'\n\x1b[1mOptimales Alignment:\x1b[0m'); + print(''); print(display_y); print(len(display_x) * '-'); print(display_x); @@ -82,6 +86,7 @@ def hirschberg_algorithm_step( Y: str, depth: int = 0, verbose: bool = False, + just_moves: bool = False, ) -> Tuple[List[str], List[str]]: n = len(Y); if n == 1: @@ -118,6 +123,7 @@ def hirschberg_algorithm_step( X2 = '-' + X2, Y1 = '-' + Y1, Y2 = '-' + Y2, + just_moves = just_moves, ); print(f'\n\x1b[1mRekursionstiefe: {depth}\x1b[0m\n\n{repr}') @@ -125,8 +131,8 @@ def hirschberg_algorithm_step( coord1, coord2 = get_optimal_transition(Costs1=Costs1, Costs2=Costs2); p = coord1[0]; # Divide and Conquer ausführen: - alignments_x_1, alignments_y_1 = hirschberg_algorithm_step(X=X[:p], Y=Y[:n], depth=depth+1, verbose=verbose); - alignments_x_2, alignments_y_2 = hirschberg_algorithm_step(X=X[p:], Y=Y[n:], depth=depth+1, verbose=verbose); + alignments_x_1, alignments_y_1 = hirschberg_algorithm_step(X=X[:p], Y=Y[:n], depth=depth+1, verbose=verbose, just_moves=just_moves); + alignments_x_2, alignments_y_2 = hirschberg_algorithm_step(X=X[p:], Y=Y[n:], depth=depth+1, verbose=verbose, just_moves=just_moves); # Resultate zusammensetzen: alignments_x = alignments_x_1 + alignments_x_2; @@ -375,10 +381,10 @@ def represent_cost_matrix( table_costs = table.copy(); table_moves = table.copy(); - table_costs[3:(3+m), 3:(3+n)] = Costs; + table_costs[3:(3+m), 3:(3+n)] = Costs.copy(); table_moves[3:(3+m), 3:(3+n)] = '·'; for (i, j) in path: - # table_costs[3 + i, 3 + j] = f'\x1b[92;1m{table_costs[3 + i, 3 + j]}\x1b[0m'; + table_costs[3 + i, 3 + j] = f'{{{table_costs[3 + i, 3 + j]}}}'; table_moves[3 + i, 3 + j] = '*'; return table_costs, table_moves; @@ -388,6 +394,7 @@ def display_cost_matrix( path: List[Tuple[int, int]], X: str, Y: str, + just_moves: bool = False, ) -> str: ''' Zeigt Kostenmatrix + optimalen Pfad. @@ -402,12 +409,13 @@ def display_cost_matrix( ''' table_costs, table_moves = represent_cost_matrix(Costs=Costs, path=path, X=X, Y=Y); # benutze pandas-Dataframe, um schöner darzustellen: - h = table_costs.shape[0]; - costs_repr = pd.DataFrame(table_costs).to_string(index=False, header=False); - moves_repr = pd.DataFrame(table_moves).to_string(index=False, header=False); - table = np.concatenate([table_costs, np.full(shape=(h, 1), dtype=object, fill_value=' '), table_moves], axis=1); + if just_moves: + table = table_moves; + else: + table = table_costs; - repr = pd.DataFrame(table).to_string(index=False, header=False); + # benutze pandas-Dataframe + tabulate, um schöner darzustellen: + repr = tabulate(pd.DataFrame(table), showindex=False, stralign='center', tablefmt='plain'); return repr; def display_cost_matrix_halves( @@ -419,6 +427,7 @@ def display_cost_matrix_halves( X2: str, Y1: str, Y2: str, + just_moves: bool = False, ) -> str: ''' Zeigt Kostenmatrix + optimalen Pfad für Schritt im D & C Hirschberg-Algorithmus @@ -435,14 +444,13 @@ def display_cost_matrix_halves( table_costs2, table_moves2 = represent_cost_matrix(Costs=Costs2, path=path2, X=X2, Y=Y2, pad=True); # merge Taellen: - h = table_costs1.shape[0]; table_costs = np.concatenate([table_costs1, table_costs2[::-1, ::-1]], axis=1); table_moves = np.concatenate([table_moves1, table_moves2[::-1, ::-1]], axis=1); - table = np.concatenate([table_costs, np.full(shape=(h, 1), dtype=object, fill_value=' '), table_moves], axis=1); + if just_moves: + table = table_moves; + else: + table = table_costs; - # benutze pandas-Dataframe, um schöner darzustellen: - # costs_repr = pd.DataFrame(table_costs).to_string(index=False, header=False); - # moves_repr = pd.DataFrame(table_moves).to_string(index=False, header=False); - # return costs_repr, moves_repr; - repr = pd.DataFrame(table).to_string(index=False, header=False); + # benutze pandas-Dataframe + tabulate, um schöner darzustellen: + repr = tabulate(pd.DataFrame(table), showindex=False, stralign='center', tablefmt='plain'); return repr;