12.1.3. Метод Гаусса
Суть метода Гаусса состоит в том, что с помощью некоторых операций исходную систему уравнений можно свести к более простой системе. Эта простая система имеет треугольный вид:
a11x1 +
| a12x2 +
| a13x3 +
| ...
| a1NxN = b1
| | a22x2 +
| a23x3 +
| ...
| a2NxN = b2
| | | a33x3 +
| ...
| a3NxN = b3
| ...
| | | | | | | | ...
| aNNxN = bN
| Особенность этой системы - в строках с номером i все коэффициенты aij при j<i равны нулю.
Если мы смогли привести нашу систему уравнений к такому треугольному виду, то решить уравнения уже просто. Из последнего уравнения находим xN= bN / aNN. Дальше подставляем его в предпоследнее уравнение и находим из него xN-1. Подставляем оба найденных решения в следующее с конца уравнение и находим xN-2. И так далее, пока не найдем x1, на чем решение заканчивается. Такая процедура называется обратной прогонкой.
Теперь перейдем к вопросу как же добиться того, чтобы система стала треугольной.
Из линейной алгебры (см. например, Крутицкая Н.И., Тихонравов А.В., Шишкин А.А., Аналитическая геометрия и линейная алгебра с приложениями) известно что если к некоторой строке системы уравнений прибавить любую линейную комбинацию любых других строк этой системы, то решение системы не изменится. Под линейной комбинацией строк понимается сумма строк, каждая из которых у множается на некоторое число (в принципе, любое).
Нужно, чтобы во второй строке получилось уравнение, в которой отсутствует член при x1. Прибавим к этой строке первую строку, умноженную на некоторое число M.
(a11x1 + a12x2 + a13x3 +... a1NxN = b1)*M + a21x1 + a22x2 + a23x3 +... a2NxN = b2
Получим
(a11*М + a21) x1 +... = b1*M + b2
Для того, чтобы член при x1 равнялся нулю, нужно, чтобы M = - a21 / a11. Проделав эту операцию, получившееся уравнение запишем вместо второго и приступим к третьему уравнению. К нему мы прибавим первое уравнение, умноженное на M = - a31 / a11 и тоже получим ноль вместо члена при x1. Такую операцию нужно проделать над всеми остальными уравнениями. В результате получим систему такого вида:
a11x1 +
| a12x2 +
| a13x3 +
| ...
| a1NxN = b1
| | a22x2 +
| a23x3 +
| ...
| a2NxN = b2
| | a32x2 +
| a33x3 +
| ...
| a3NxN = b3
| ...
| | | | | | aN2x2 +
| aN3x3 +
| ...
| aNNxN = bN
| После этого будем избавляться от членов при x2 в третьем, четвертом, N-ом уравнении. Для этого нужно к уравнению с j-м номером прибавить 2-ое уравнение, умноженное на M = - aj2 / a22. Проделав эту операцию над всеми остальными уравнениями, получим систему где нет членов с x2 в уравнениях с номером больше 2.
И так далее... Проделав это для третьего члена, четвертого... до тех пор, пока не кончатся уравнения, получим в итоге систему треугольного вида.
Один из основных недостатков метода Гаусса связан с тем, что при его реализации накапливается вычислительная погрешность. Для того, чтобы уменьшить рост вычислительной погрешности применяются различные модификации метода Гаусса. Например, метод Гаусса с выбором главного элемента по столбцам, в этом случае на каждом этапе прямого хода строки матрицы переставляются таким образом, чтобы диагональный угловой элемент был максимальным. При исключении соответствующего неизвестного из других строк деление будет производиться на наибольший из возможных коэффициентов и следовательно относительная погрешность будет наименьшей. Существует метод Гаусса с выбором главного элемента по всей матрице. В этом случае переставляются не только строки, но и столбцы. Использование модификаций метода Гаусса приводит к усложнению алгоритма увеличению числа операций и соответственно к росту времени счета. Поэтому целесообразность выбора того или иного метода определяется непосредственно программистом Выполняемые в методе Гаусса преобразования прямого хода, приведшие матрицу А системы к треугольному виду позволяют вычислить определитель матрицы
Пример
10 print "Решение системы линейных уравнений методом
20 print "Гаусса с выбором главного элемента
30 input "Задайте число уравнений"N
40 dim A(N,N),B(N),C(N,N),G(N),X(N)
50 for i=1 to N:for j=1 to N
60? "Введите A("I","J")=";:input A(i,j):next j
70? "Введите B("I")";:input B(i):next i
80 gosub 100
85 for i=1 to N
90? "X("I")=";X(I);:next I:stop
100 N1=N-1:for K=1 to N1
110 if ABS(A(K,K))>0 goto 200
120 K1=K+1:for M=K1 to N
130 if ABS(A(M,K))>0 goto 150
140 goto 165
150 for L=1 to N:V=A(K,L):A(K,L)=A(M,L)
160 A(M,L)=V:next L
165 next M
170 V=B(K):B(K)=B(M):B(M)=V
200 G(K)=B(K)/A(K,K):K1=K+1
210 for I=K1 to N:B(I)=B(i)-A(i,k)*G(k)
220 for J1=K to N
J=N-J1+K
C(K,J)=A(K,J)/A(K,K)
225 A(I,J)=A(I,J)-A(I,K)*C(K,J)
230 next J1:next I:next K
240 M=N:X(M)=B(M)/A(M,M)
250 M=M-1:S=0:for L=M to N1
260 S=S+C(M,L+1)*X(L+1):next L
270 X(M)=G(M)-S:If M>1 goto 250
280 return:end
|