Метод Гаусса — Зейделя (метод Зейделя, процесс Либмана, метод последовательных замещений) — является классическим итерационным методом решения системы линейных уравнений.
Возьмём систему: , где
Или
И покажем, как её можно решить с использованием метода Гаусса-Зейделя.
Чтобы пояснить суть метода, перепишем задачу в виде
Здесь в -м уравнении мы перенесли в правую часть все члены, содержащие , для . Эта запись может быть представлена как
где в принятых обозначениях означает матрицу, у которой на главной диагонали стоят соответствующие элементы матрицы , а все остальные нули; тогда как матрицы и содержат верхнюю и нижнюю треугольные части , на главной диагонали которых нули.
Итерационный процесс в методе Гаусса — Зейделя строится по формуле
после выбора соответствующего начального приближения .
Метод Гаусса — Зейделя можно рассматривать как модификацию метода Якоби. Основная идея модификации состоит в том, что новые значения используются здесь сразу же по мере получения, в то время как в методе Якоби они не используются до следующей итерации:
где
Таким образом, i-я компонента -го приближения вычисляется по формуле
Например, при :
Приведём достаточное условие сходимости метода.
![]() |
Теорема. Пусть , где – матрица, обратная к . Тогда при любом выборе начального приближения :
|
Условие окончания итерационного процесса Зейделя при достижении точности в упрощённой форме имеет вид:
Более точное условие окончания итерационного процесса имеет вид
и требует больше вычислений. Хорошо подходит для разреженных матриц.
1 // Условие окончания
2 bool converge(double *xk, double *xkp)
3 {
4 double norm = 0;
5 for (int i = 0; i < n; i++)
6 norm += (xk[i] - xkp[i])*(xk[i] - xkp[i]);
7 return (sqrt(norm)<eps);
8 }
9
10 /*
11 Ход метода, где:
12 a[n][n] - Матрица коэффициентов
13 x[n], p[n] - Текущее и предыдущее решения
14 b[n] - Столбец правых частей
15 Все перечисленные массивы вещественные и
16 должны быть определены в основной программе,
17 также в массив x[n] следует поместить начальное
18 приближение столбца решений (например, все нули)
19 */
20
21 do
22 {
23 for (int i = 0; i < n; i++)
24 p[i] = x[i];
25 for (int i = 0; i < n; i++)
26 {
27 double var = 0;
28 for (int j = 0; j < i; j++)
29 var += (a[i][j] * x[j]);
30 for (int j = i + 1; j < n; j++)
31 var += (a[i][j] * p[j]);
32 x[i] = (b[i] - var) / a[i][i];
33 }
34 }
35 while (!converge(x, p));
type ar2d = array [1..50, 1..50] of double;
ar1d = array [1..50] of double;
procedure seidel(n: byte; e: extended; a: ar2d; b: ar1d; x: ar1d);
var i, j: longint;
v, m: double;
begin
// Проверка на совместность
for i := 1 to n do
begin
for j := 1 to n do
if j <> i then
begin
if abs(a[i, j]) >= abs(a[i, i]) then
begin
writeln('SLAE is inconsistent');
exit;
end;
end;
end;
// Сам алгоритм
repeat
m := 0;
for i := 1 to n do
begin
s := 0;
for j := 1 to n do
if i <> j then s := s + a[i, j] * x[j];
v := x[i];
x[i] := (b[i] - s) / a[i, i];
m:=abs(x[i]-v);
end;
until m > e;
// Вывод корней
writeln('roots: ');
for i := 1 to n do
writeln('x[', i, ']= ', x[i]:0:4);
end;
from math import sqrt
import numpy as np
def seidel(A, b, eps):
n = len(A)
x = [.0 for i in range(n)]
converge = False
while not converge:
x_new = np.copy(x)
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]
converge = sqrt(sum((x_new[i] - x[i]) ** 2 for i in range(n))) <= eps
x = x_new
return x
Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".
Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.
Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .