Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 148 additions & 0 deletions Р3265-69/fedorova_367582/lab1/lab_1
Original file line number Diff line number Diff line change
@@ -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()