Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
57
Добавлен:
28.05.2015
Размер:
770.34 Кб
Скачать

xi = i , где i = 1, 2, …, n.

Очевидно, решение существует только в том случае, если ∆ ≠ 0 . Данный метод эффективен при небольших размерах матрицы А.

2.2 Метод исключений Гаусса

Как и предыдущий, данный метод применяется для решения систем линейных уравнений вида

 

 

A X = B ,

(2.1)

где

А

квадратная матрица размера n x n;

 

 

Х

n-мерный вектор неизвестных;

 

 

В

n-мерный вектор констант.

 

Метод Гаусса основывается на том факте, что сложение одного уравнения системы с другим или умножение уравнения на постоянное число не изменяет решения системы.

Рассмотрим алгоритм исключений Гаусса на примере системы вида (2.1) из трех уравнений:

a11x1 +a12 x2 +a13x3 = b1

 

a21x1 +a22 x2

+a23x3

= b2

(2.2)

a x

+a x

2

+a

33

x

= b

 

 

31

1

32

 

3

3

 

Предположим, что коэффициент a11 0. (Если это не так, то проще всего сложить первое уравнение системы (2.2) с любым другим, у которого коэффициент при переменной x1 отличен от нуля.) Ко второму уравнению прибавим первое, умноженное на коэффициент (a21a11) , а к третьему — первое, умноженное на коэффициент (a31 a11) . В результате этих действий из второго и третьего уравнений будет исключена переменная x1:

a x

+a x

2

+a x

= b

 

 

11

1

12

 

13

3

1

 

0

x1

+a22(1) x2

+a23(1) x3

= b2(1)

(2.3)

0

x

+a(1) x

2

+a(1) x

3

= b(1)

 

 

1

 

32

 

33

3

 

23.

Здесь a(1)

= a

22

a21

a

,

a(1)

= a

23

a21

a

,

b(1)

= b

a21

b ,

 

 

 

 

 

 

22

 

 

 

a11

12

 

23

 

 

 

a11

13

 

2

2

1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

a11

a(1)

= a

32

a31

 

a

,

a(1)

= a

33

a31

 

a

,

b(1)

= b

a31

b .

 

 

 

32

 

 

 

a11

12

 

33

 

 

 

a11

13

 

3

3

1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

a11

Верхний индекс (1) означает, что соответствующий коэффициент подвергся однократному пересчету. Нетрудно убедиться, что матрицы коэффициентов в новой системе (2.3) могут быть получены из исходных (2.2) путем умножения на элементарную матрицу ε1:

a11

a12

a13

 

 

 

 

b1

 

 

 

0

a(1)

a(1)

 

= ε A ,

 

b(1)

 

= ε B ,

 

 

22

 

23

 

 

1

 

 

2

 

1

 

0

a(1)

a(1)

 

 

 

 

b(1)

 

 

 

 

32

 

33

 

 

 

 

 

3

 

 

где

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

 

0

0

 

 

 

 

 

ε

=

a

21

a

1

0

 

 

(2.4)

 

 

1

 

a

11

0

 

 

 

 

 

 

 

 

31

a

1

 

 

 

 

 

 

 

 

11

 

 

 

 

 

Предположим, что a22(1) 0 (в противном случае см. замечание выше).

Исключим переменную х2 из первого и третьего уравнений системы (2.3). Для этого к первому уравнению прибавим второе, умноженное на коэффици-

ент (a12 a22(1) ), а к третьему прибавим второе, умноженное на коэффициент

(a32(1) a22(1) ):

a

x

+0 x

2

+a(1) x

= b(1)

 

 

11

1

 

 

13

3

1

 

 

 

 

a22(1) x2

+a23(1) x3

= b2(1)

(2.5)

 

 

 

 

 

 

0 x

2

+a(2) x

3

= b(2)

 

 

 

 

 

 

 

 

33

3

 

 

 

 

 

 

Нетрудно убедиться, что система (2.5) может быть получена из (2.4)

умножением матриц коэффициентов на элементарную матрицу ε2:

24.

a

0

a(1)

 

 

 

b(1)

 

 

 

 

11

a(1)

13

 

= ε

ε A ,

 

1

 

= ε

ε B , где

0

a(1)

 

b(1)

 

 

 

22

23

 

 

2 1

 

2

 

 

2 1

 

0

0

a(2)

 

 

 

b(2)

 

 

 

 

 

 

33

 

 

 

 

3

 

 

 

 

1

a

a(1)

0

 

ε2

 

12

22

 

(2.6)

= 0

1

 

0

 

0

a(1)

a(1)

1

 

 

 

32

22

 

 

Далее, действуя аналогично, исключаем в системе (2.5) переменную х3 из первого и второго уравнения. Для этого воспользуемся элементарной матрицей ε3:

 

 

 

 

1

0

a(1)

a(2)

 

 

 

 

 

 

ε

 

 

 

1

 

 

13

33

 

 

 

 

(2.7)

 

3

= 0

 

a(1)

a(2)

 

 

 

 

 

 

 

 

 

 

 

23

33

 

 

 

 

 

 

 

 

 

0

0

 

1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

a

 

0

 

0

 

 

 

b(2)

 

 

 

11

 

(1)

 

 

,

 

 

 

1

 

ε ε ε A =

0

 

a

 

0

ε ε ε B = b(2)

,

3 2 1

 

 

 

22

 

 

 

3 2 1

 

2

 

 

 

0

 

0

a

(2)

 

 

 

(2)

 

 

 

33

 

 

 

b

 

 

 

 

 

 

 

 

 

 

 

3

 

и система уравнений преобразуется к тривиальному виду

 

 

 

 

 

 

 

a

x

= b(2)

 

 

 

 

 

 

 

 

 

 

 

11

1

 

1

 

 

 

 

 

 

 

 

 

 

 

(1)

 

 

(2)

 

 

 

 

 

(2.8)

 

 

 

 

a22 x2

= b2

 

 

 

 

 

 

 

 

 

a(2) x

= b(2)

 

 

 

 

 

 

 

 

 

 

 

 

3

 

 

 

 

 

 

 

 

 

 

 

 

 

33

 

3

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Придерживаясь методики умножения на элементарные матрицы, воспользуемся диагональной матрицей s:

1 a

0

0

 

 

 

11

1 a22(1)

0

 

(2.9)

s =

0

 

 

0

0

(2)

 

 

 

1 a33

 

 

Поскольку 3ε2ε1A =1,

решение исходной системы уравнений опре-

деляется выражением

25.

 

b(3)

 

 

 

1

 

(2.10)

X = sε ε ε B = b(3)

 

3 2 1

2

 

 

 

b(3)

 

 

 

3

 

 

Замечания.

Элементарные матрицы εi образуются из единичной матрицы порядка n путем замены нулевых элементов i-го столбца. Эти матрицы могут быть найдены строго последовательно друг за другом. Например, чтобы сформиро-

вать матрицу ε2, сначала надо выполнить произведение ε1А и т.д. Результаты произведений элементарных матриц на матрицы А и В мо-

гут располагаться в тех же массивах, что и матрицы А и В.

При реальном программировании удобно матрицы коэффициентов А и В объединить в одну, так называемую присоединенную матрицу Aпр =[A;B].

Для нее справедливо:

n ...ε2ε1Aпр =[n ...ε2ε1A; n ...ε2ε1B]=[1;X],

т.е. после выполнения произведений ее правый столбец будет содержать решение.

Методом Гаусса можно найти обращенную матрицу. Действительно,

раз 3ε2ε1A =1,

 

 

 

sε ε ε = A1

(2.11)

3

2

1

 

Для обращения формируется присоединенная матрица вида Aпр =[A;1].

Определитель матрицы А, det A =1det s , т.е. равен обратной величине от произведения диагональных элементов матрицы s.

Поскольку расположение нулей в элементарных матрицах заранее известно, легко построить алгоритм, исключающий ненужные произведения на ноль.

Ниже приведен текст программы, написанной на языке Турбо Си и реализующей описанную выше процедуру поиска решения. Программа работает с присоединенной матрицей, элементы которой вводятся последователь-

26.

но с клавиатуры. Перед вводом значения элемента на экран выводятся его координаты, например, «(1,1):». После ввода последнего элемента на экран выводится введенная матрица, а следом за ней — результат после исключений Гаусса. Правый столбец этой матрицы содержит решение системы уравнений.

Листинг программы решения системы линейных уравнений методом Гаусса

#include <stdio.h> #include <alloc.h> #include <math.h> #include <conio.h>

double *data;

/* Объявляем имя и тип матрицы

*/

char buffer[20];

/* Вспомогательный символьный массив

*/

double Mnul=1e-15, det=1.0;

/* "Машинный нуль" и начальное

*/

 

/* значение определителя

*/

/* Решение системы уравнений методом Гаусса с попутным вычислением

*/

/* определителя матрицы коэффициентов. Программа работает с

*/

/* "присоединенной" матрицей, образованной стыковкой матрицы

*/

/* коэффициентов и столбца свободных членов

*/

main()

 

 

{

 

 

int row, col;

 

 

int i,j,k,n;

 

 

double m;

 

 

/*Вводим размер системы уравнений */

printf("\nЧисло строк = "); scanf("%d",&row);

col=row+1; /* Число столбцов присоединенной матрицы всегда больше на 1 */

/* Выделяем память под матрицу заданного размера */

 

data=(double*)malloc(row*col*sizeof(double));

 

/*

Заносим значения в массив (с клавиатуры).

*/

/*

Замечание: традиционное обращение к элементам массива "data[i][j]"

*/

/* в данной программе не применяется, поскольку изначально размерность */ /* массива не определена. Вместо него используется аналогичная по сути */

/*

процедура взятия ссылки с адреса, рассчитываемого по формуле

*/

/*

*(data+i*col+j),

*/

/* где col-количество элементов в строке массива(т.е. число столбцов). */

/* другими словами, "data[i][j]" = "*(data+i*col+j)"

*/

for(i=0;i<row;i++)

 

 

for(j=0;j<col;j++)

 

 

{

/* Приглашение к вводу с клавиатуры */

printf("(%d,%d):",i+1,j+1);

scanf("%s",buffer); /*Строка введенных символов помещается в buffer,*/ *(data+i*col+j)=atof(buffer); /* преобразуется в число и заносится

в массив */

}

27.

/* Печатаем введенную присоединенную матрицу */

for(i=0;i<row;i++){

for(j=0;j<col;j++)

printf("%10.4f",*(data+i*col+j));

printf("\n");

}

printf("\n");

/**** Исключение переменных по методу Гаусса ****/

for(k=0; k<row; k++){

/* Если диагональный элемент

*/

if(fabs(*(data+k*col+k)) < Mnul)

{

for(n=k+1; n<row; n++)

/* на k-м шаге равен нулю,

*/

 

/* ищем строку ниже с

*/

 

if(fabs(*(data+n*col+k)) > Mnul) /* ненулевым элементом в

*/

 

break;

/* k-м столбце.

*/

 

if(n==row)

/* Если такой строки нет,

*/

 

{

/* Выходим из программы.

*/

 

printf("Система не имеет решения. Шаг N %d:\n",k+1);

 

 

for(i=0;i<row;i++)

/* Печать матрицы перед выходом */

 

{

 

 

 

for(j=0;j<col;j++)

 

 

 

printf("%10.4f",*(data+i*col+j));

 

 

printf("\n");

 

 

 

}

 

 

 

printf("Press any key to exit...\n");

 

 

i=getch();

 

 

 

exit(1);

/*А если есть, то складываем ее */

 

}

 

for(j=k; j<col; j++)

/*с текущей k-й строкой.

*/

 

 

 

}

*(data+k*col+j) += *(data+n*col+j);

 

/* Так мы избавились от нуля на главной диагонали, */

 

/* не изменив значения определителя матрицы.

*/

for(j = k, m = *(data+k*col+k); j<col; j++)

*/

*(data+k*col+j) /= m;

/* Нормализация строки,

det *= m;

/* т.е. деление на диагональный элемент */

/* Накопление определителя.

*/

for(n=0; n<row; n++)

/* Исключение k-й переменной

*/

{

/* по методу Гаусса из всех

*/

if(n==k) continue;

/* уравнений, кроме k-го.

*/

m = -*(data+n*col+k);

 

 

for(j = k; j < col; j++)

 

*(data+n*col+j) += m*(*(data+k*col+j));

 

}

/* Конец прямого исключения переменных */

 

}

 

/* Печать преобразованной присоединенной матрицы (для контроля). */ /* В левой части должна получиться единичная матрица, а в правом */ /* столбце - решение системы. */

for(i=0;i<row;i++){

for(j=0;j<col;j++)

printf("%10.4f",*(data+i*col+j));

printf("\n");

}

printf("Определитель равен %f\nРешение находится в правом столбце.\n\ Нажмите любую клавишу...\n",det);

free(data);

/* Ожидание нажатия любой клавиши */

i=getch();

}

 

28.