diff --git a/Л3-В6/Программа/src/algorithm.py b/Л3-В6/Программа/src/algorithm.py index 22deeed..55a12d8 100644 --- a/Л3-В6/Программа/src/algorithm.py +++ b/Л3-В6/Программа/src/algorithm.py @@ -50,34 +50,54 @@ def swap_first_non_zero(matrix, i): return False, -1 -def swap_max_row(matrix, i): +def swap_max_row(matrix, j): n = matrix.shape[0] - col_max = abs(matrix[i, i]) - max_j = i - for j in range(i, n): - if abs(matrix[j, i]) > col_max: - col_max = abs(matrix[j, i]) - max_j = j - if i != max_j: - matrix[[i, max_j], :] = matrix[[max_j, i], :] + current = float("inf") + if matrix[j, j] != 0: + current = np.sum(np.abs(matrix[j, :])) / abs(matrix[j, j]) + max_i = j + for i in range(j + 1, n): + if matrix[i, j] == 0 or matrix[j, i] == 0: + continue - return max_j + target_current = np.sum(np.abs(matrix[i, :])) / abs(matrix[i, i]) + new = np.sum(np.abs(matrix[i, :])) / abs(matrix[i, j]) + target_new = np.sum(np.abs(matrix[j, :])) / abs(matrix[j, i]) + + if current - new > target_new - target_current: + current = new + max_i = i + + if j != max_i: + matrix[[j, max_i], :] = matrix[[max_i, j], :] + + return max_i def swap_max_column(matrix, i): n = matrix.shape[0] - row_max = abs(matrix[i, i]) - max_j = i - for j in range(i, n): - if abs(matrix[i, j]) > row_max and abs(matrix[i, i]) - abs(matrix[j, j]) > 0.0: - row_max = abs(matrix[i, j]) - max_j = j - if i != max_j: - matrix[:, [i, max_j]] = matrix[:, [max_j, i]] + current = float("inf") + if matrix[i, i] != 0: + current = np.sum(np.abs(matrix[i, :])) / abs(matrix[i, i]) + best_j = i + for j in range(i + 1, n): + if matrix[i, j] == 0 or matrix[j, i] == 0: + continue - return max_j + target_current = np.sum(np.abs(matrix[j, :])) / abs(matrix[j, j]) + new = np.sum(np.abs(matrix[i, :])) / abs(matrix[i, j]) + target_new = np.sum(np.abs(matrix[j, :])) / abs(matrix[j, i]) + + if current - new > target_new - target_current: + current = new + best_j = j + + if i != best_j: + matrix[:, [i, best_j]] = matrix[:, [best_j, i]] + + return best_j def norm(matrix: np.matrix): diff --git a/Л3-В6/Программа/src/main.py b/Л3-В6/Программа/src/main.py index f7e7227..a62f042 100644 --- a/Л3-В6/Программа/src/main.py +++ b/Л3-В6/Программа/src/main.py @@ -14,17 +14,17 @@ A = np.matrix( B = np.matrix([[15.5, 2.5, 8.6, 12.1]], dtype=np.float64).T -# A = np.matrix( -# [ -# [14.4, -5.3, 14.3, -12.7], -# [23.4, -14.2, -5.4, 2.1], -# [6.3, -13.2, -6.5, 14.3], -# [5.6, 8.8, -6.7, -23.8], -# ], -# dtype=np.float64, -# ) +A = np.matrix( + [ + [14.4, -5.3, 14.3, -12.7], + [23.4, -14.2, -5.4, 2.1], + [6.3, -13.2, -6.5, 14.3], + [5.6, 8.8, -6.7, -23.8], + ], + dtype=np.float64, +) -# B = np.matrix([[-14.4, 6.6, 9.4, 7.3]], dtype=np.float64).T +B = np.matrix([[-14.4, 6.6, 9.4, 7.3]], dtype=np.float64).T # A = np.matrix( @@ -48,7 +48,7 @@ B = np.matrix([[15.5, 2.5, 8.6, 12.1]], dtype=np.float64).T # print(algorithm.cond(A)) # print(np.linalg.cond(A, p=float("inf"))) -# koef = np.matrix([[1 / 10000000000000, 1/100000000000, 1, 1]], dtype=np.float64) +# koef = np.matrix([[1, 1, 1, 1]], dtype=np.float64) # for i in range(A.shape[0]): # A[i, :] *= koef[0, i] # B[i, :] *= koef[0, i] diff --git a/Л3-В6/Программа/src/solution.py b/Л3-В6/Программа/src/solution.py index bd0b6b1..bc051c8 100644 --- a/Л3-В6/Программа/src/solution.py +++ b/Л3-В6/Программа/src/solution.py @@ -1,3 +1,4 @@ +from typing import List, Tuple import algorithm import numpy as np @@ -13,28 +14,26 @@ def iterative_method( alpha = np.copy(A) beta = np.copy(B) - for i in range(n): - j = algorithm.swap_max_row(alpha, i) - - if alpha[i, i] == 0: - return None - - beta[[i, j], :] = beta[[j, i], :] + print(alpha) swaps = [] for i in range(n): - j = algorithm.swap_max_column(alpha, i) - - if alpha[i, i] == 0: + if not _swap_rows(alpha, beta): return None - swaps.append((i, j)) + success, swaps_ = _swap_columns(alpha) + if not success: + return None + + swaps.extend(swaps_) + + print(alpha) + + print(alpha) for i in range(n): beta[i, 0] = beta[i, 0] / alpha[i, i] - X = np.copy(beta) - for i in range(n): for j in range(n): if i == j: @@ -44,12 +43,13 @@ def iterative_method( alpha[i, i] = 0 - print(algorithm.cond(alpha)) + print(algorithm.norm(alpha)) - if algorithm.cond(alpha) >= 1.0: + if algorithm.norm(alpha) >= 1.0: return None i = 0 + X = np.copy(beta) while i < max_iterations: i += 1 @@ -63,3 +63,31 @@ def iterative_method( X[[i, j], :] = X[[j, i], :] return X + + +def _swap_rows(a: np.matrix, b: np.matrix) -> bool: + n = a.shape[0] + for i in range(n): + j = algorithm.swap_max_row(a, i) + + if a[i, i] == 0: + return False + + b[[i, j], :] = b[[j, i], :] + + return True + + +def _swap_columns(a: np.matrix) -> Tuple[bool, List[Tuple[int, int]] | None]: + n = a.shape[0] + swaps = [] + for i in range(n): + j = algorithm.swap_max_column(a, i) + + if a[i, i] == 0: + return False, None + + if i != j: + swaps.append((i, j)) + + return True, swaps