Skip to content
Open
Show file tree
Hide file tree
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
Binary file not shown.
175 changes: 175 additions & 0 deletions Р3212/vildanov_408379/lab1/functions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import math
import random

def is_integer(s: str) -> bool:
s2 = s.strip()
if s2.startswith('-'):
s2 = s2[1:]
return s2.isdigit()

def is_float(s: str) -> bool:
s2 = s.strip()
if s2.startswith('-'):
s2 = s2[1:]
if s2.count('.') > 1:
return False
if '.' in s2:
parts = s2.split('.')
return all(part.isdigit() for part in parts if part != '')
return s2.isdigit()

def read_matrix_file(filename: str):
try:
f = open(filename, 'r')
except IOError:
return None
lines = [line.strip() for line in f if line.strip() != '']
f.close()
if len(lines) < 3:
return None
# n
if not is_integer(lines[0]):
return None
n = int(lines[0])
if n <= 0:
return None
# tol
if not is_float(lines[1]):
return None
tol = float(lines[1])
if tol <= 0:
return None
# max_iters
if not is_integer(lines[2]):
return None
max_iters = int(lines[2])
if max_iters <= 0:
return None
data_lines = lines[3:]
if len(data_lines) != n:
return None
mat = []
for row_str in data_lines:
parts = row_str.split()
if len(parts) != n + 1:
return None
if not all(is_float(tok) for tok in parts):
return None
mat.append([float(tok) for tok in parts])
return mat, n, tol, max_iters

def read_matrix_user():
while True:
s = input("Введите порядок системы (целое > 0): ").strip()
if is_integer(s) and int(s) > 0:
n = int(s)
break
print("Ошибка: нужно целое положительное число.")
while True:
s = input("Введите точность (вещественное > 0): ").strip()
if is_float(s) and float(s) > 0:
tol = float(s)
break
print("Ошибка: нужно вещественное число > 0.")
while True:
s = input("Введите макс. число итераций (целое > 0): ").strip()
if is_integer(s) and int(s) > 0:
max_iters = int(s)
break
print("Ошибка: нужно целое число > 0.")
print(f"Теперь введите расширенную матрицу ({n} строк по {n+1} чисел):")
mat = []
for i in range(n):
row_str = input(f"Строка {i+1}: ").strip().split()
if len(row_str) != n + 1:
return None
if not all(is_float(tok) for tok in row_str):
return None
mat.append([float(tok) for tok in row_str])
return mat, n, tol, max_iters

def random_matrix():
while True:
s = input("Введите порядок системы (целое > 0): ").strip()
if is_integer(s) and int(s) > 0:
n = int(s)
break
print("Ошибка: нужно целое положительное число.")
while True:
s = input("Введите точность (вещественное > 0): ").strip()
if is_float(s) and float(s) > 0:
tol = float(s)
break
print("Ошибка: нужно вещественное число > 0.")
while True:
s = input("Введите макс. число итераций (целое > 0): ").strip()
if is_integer(s) and int(s) > 0:
max_iters = int(s)
break
print("Ошибка: нужно целое число > 0.")
mat = [[float(random.randint(1, 9)) for _ in range(n + 1)] for _ in range(n)]
return mat, n, tol, max_iters

def check_diagonal(mat):
n = len(mat)
strict_found = False
for i in range(n):
s = 0.0
for j in range(n):
if i == j:
continue
s += abs(mat[i][j])
if abs(mat[i][i]) < s:
return False
if abs(mat[i][i]) > s:
strict_found = True
return strict_found

def matrix_norm(mat):
n = len(mat)
best = 0.0
for i in range(n):
row_sum = sum(abs(mat[i][j]) for j in range(n))
if row_sum > best:
best = row_sum
return best

def gauss_seidel(mat, n, tol, max_iters, order):
x_old = [0.0] * n
x_new = [0.0] * n
errors = [0.0] * n
iters = 0
diff = tol + 1.0

while diff > tol and iters < max_iters:
for i in range(n):
s = 0.0
for j in range(n):
if j != i:
s += mat[i][j] * x_new[j]
x_new[i] = (mat[i][n] - s) / mat[i][i]

diff = 0.0
for i in range(n):
d = abs(x_new[i] - x_old[i])
errors[i] = d
if d > diff:
diff = d

x_old = x_new.copy()
iters += 1

if diff > tol:
return None, None, iters

final = [0.0] * n
for idx_new, orig_idx in enumerate(order):
final[orig_idx] = x_new[idx_new]
return final, errors, iters

def print_matrix(mat):
n = len(mat)
for i in range(n):
line = " ".join(f"{mat[i][j]:>7.3f}" for j in range(n))
line += " | " + f"{mat[i][n]:>7.3f}"
print(line)
88 changes: 88 additions & 0 deletions Р3212/vildanov_408379/lab1/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
from functions import (
read_matrix_file,
read_matrix_user,
random_matrix,
check_diagonal,
matrix_norm,
gauss_seidel,
print_matrix
)

def main():
print("=== Решение СЛАУ методом Гаусса–Зейделя ===")
print("1) Ввод с клавиатуры")
print("2) Загрузка из файла")
print("3) Случайная матрица")
choice = input("Выберите режим (1/2/3): ").strip()

if choice == "1":
data = read_matrix_user()
elif choice == "2":
data = read_matrix_file("input.txt")
elif choice == "3":
data = random_matrix()
else:
print("Некорректный выбор, выход.")
return

if data is None:
print("\nОшибка при получении матрицы. Проверьте ввод.")
return

mat, n, tol, max_iters = data

print("\n=== Введённая (или загруженная) расширенная матрица ===")
print_matrix(mat)
print(f"\nТочность: {tol:.6g}")
print(f"Максимум итераций: {max_iters}\n")

order = list(range(n))

if check_diagonal(mat):
print("Диагональное преобладание выполняется.\n")
else:
print("Нет диагонального преобладания, идет перестановка столбцов...\n")
for i in range(n):
s = sum(abs(mat[i][j]) for j in range(n) if j != i)
if abs(mat[i][i]) < s:
best_j = i
best_val = abs(mat[i][i])
for j in range(n):
if j != i and abs(mat[i][j]) > best_val:
best_val = abs(mat[i][j])
best_j = j
if best_j != i and best_val > s:
for row in range(n):
mat[row][i], mat[row][best_j] = mat[row][best_j], mat[row][i]
order[i], order[best_j] = order[best_j], order[i]
if check_diagonal(mat):
break

if check_diagonal(mat):
print("Достигнуто диагональное преобладание после перестановки.\n")
else:
print("Не удалось обеспечить диагональное преобладание.\n")

print("=== Новый вид матрицы после перестановок ===")
print_matrix(mat)
print()

for i in range(n):
if abs(mat[i][i]) < 1e-15:
print("На диагонали найден ноль, решение невозможно.")
return

norm_val = matrix_norm(mat)
print(f"Норма матрицы коэффициентов: {norm_val:.6g}\n")

solution, errors, iters = gauss_seidel(mat, n, tol, max_iters, order)
if solution is None:
print(f"[НЕ СОШЛОСЬ] На {iters}-й итерации не удалось добиться точности {tol}.")
return

print(f"Решение найдено за {iters} итераций:")
print("Вектор решений x =", solution)
print("Вектор погрешностей r =", errors)

if __name__ == "__main__":
main()
Binary file not shown.
Loading