diff --git "a/\320\2403265-69/fedorova_367582/lab1/lab_1" "b/\320\2403265-69/fedorova_367582/lab1/lab_1" new file mode 100644 index 0000000..b4127d5 --- /dev/null +++ "b/\320\2403265-69/fedorova_367582/lab1/lab_1" @@ -0,0 +1,148 @@ +import numpy as np + +def read_input(): # чтение входных данных + while True: + source = input("Ввод данных: файл (F) или клавиатура (K)? ").strip().upper() + if source == 'F': + filename = input("Имя файла: ") + with open(filename, 'r') as f: + try: + n = int(f.readline().strip()) + a = [list(map(float, f.readline().split())) for _ in range(n)] + + if any(len(row) != n for row in a): + raise ValueError("Ошибка: каждая строка матрицы A должна содержать ровно n чисел.") + + b = list(map(float, f.readline().split())) + if len(b) != n: + raise ValueError("Ошибка: вектор b должен содержать n элементов.") + + eps = float(f.readline().strip()) + M = int(f.readline().strip()) + except (ValueError, IndexError): + print("Ошибка чтения файла. Проверьте формат входных данных.") + continue + break + elif source == 'K': + try: + n = int(input("Размерность n: ")) + a = [] + print("Введите матрицу A (по одной строке):") + for i in range(n): + row = list(map(float, input().split())) + if len(row) != n: + raise ValueError(f"Ошибка: строка {i + 1} должна содержать ровно {n} чисел.") + a.append(row) + + print("Введите вектор b:") + b = list(map(float, input().split())) + if len(b) != n: + raise ValueError(f"Ошибка: вектор b должен содержать ровно {n} элементов.") + + eps = float(input("Введите точность ε: ")) + M = int(input("Введите макс. итераций M: ")) + except ValueError as e: + print(f"Ошибка ввода: {e}") + continue + break + else: + print("Ошибка: введите 'F' для файла или 'K' для клавиатуры.") + + # Автоматическое задание начального приближения x0 = d + x0 = [b[i] / a[i][i] for i in range(n)] + return n, a, b, x0, eps, M + + +def check_diagonal_dominance(a): #Проверяет, является ли матрица A диагонально преобладающей + n = len(a) + for i in range(n): + diag = abs(a[i][i]) + row_sum = sum(abs(a[i][j]) for j in range(n) if j != i) + if diag <= row_sum: + return False + return True + + +def swap_matrix(a, b): # Попытка перестановки строк матрицы для достижения диагонального преобладания + n = len(a) + for i in range(n): + max_row = find_max_row(a, i, n) + if i != max_row: + a[i], a[max_row] = a[max_row], a[i] + b[i], b[max_row] = b[max_row], b[i] + return a, b + + +def find_max_row(a, i, n): + max_value = i + max_row = i + for r in range(i, n): + if abs(a[r][i]) > max_value: + max_value = abs(a[r][i]) + max_row = r + return max_row + + +def matrix_norm(c): # Вычисляет норму матрицы C + return max(sum(abs(x) for x in row) for row in c) + + +def gauss_zeidel(a, b, x0, eps, M): # Метод Гаусса-Зейделя + n = len(a) + x = x0.copy() + errors = [] + for k in range(M): + x_new = x.copy() + max_error = 0 + for i in range(n): + s1 = sum(a[i][j] * x_new[j] for j in range(i)) + s2 = sum(a[i][j] * x[j] for j in range(i + 1, n)) + x_new[i] = (b[i] - s1 - s2) / a[i][i] + error = abs(x_new[i] - x[i]) + if error > max_error: + max_error = error + errors.append(max_error) + # Вывод вектора после каждой итерации + print(f"\nИтерация {k+1}:") + print("Вектор неизвестных:", np.round(x_new, 6)) + if max_error < eps: + return x_new, k + 1, errors + x = x_new + return x, M, errors + + +def main(): + n, a, b, x0, eps, M = read_input() + + if not check_diagonal_dominance(a): + print("Диагональное преобладание отсутствует. Попытка перестановки...") + a, b = swap_matrix(a, b) + if not check_diagonal_dominance(a): + print("Невозможно достичь диагонального преобладания.") + return + else: + print("Перестановка выполнена успешно.") + # Обновляем x0 после перестановки + x0 = [b[i] / a[i][i] for i in range(n)] + + c = [] + d = [] + for i in range(n): + c_row = [-a[i][j] / a[i][i] if i != j else 0 for j in range(n)] + c.append(c_row) + d.append(b[i] / a[i][i]) + + norm = matrix_norm(c) + print(f"Норма матрицы C: {norm:.4f}") + + solution, iterations, errors = gauss_zeidel(a, b, x0, eps, M) + + print("\nВектор неизвестных:") + print(np.array(solution)) + print(f"Количество итераций: {iterations}") + print("Вектор погрешностей:") + print(np.array(errors)) + + +if __name__ == "__main__": + main()