
- •1 Цель работы
- •2 Краткие теоретические сведения
- •3 Составление блок-схем алгоритмов программ (БСА)
- •3.1 Описание символов, применяемых в БСА программ
- •3.2 Правила применения символов и выполнения схем
- •3.3 Примеры выполнения схем
- •4 Программа работы
- •Лабораторная работа №2 «Решение систем линейных уравнений»
- •1 Цель работы
- •2 Краткие теоретические сведения
- •2.1 Метод Крамера
- •2.2 Метод исключений Гаусса
- •2.3 Метод LU–разложения (LU–факторизации)
- •3 Порядок работы
- •4 Методические указания к выполнению работы
- •5 Содержание отчета о лабораторной работе
- •1 Цель работы
- •2 Краткие теоретические сведения
- •Листинг программы интегрирования СДУ (2.16)
- •3 Порядок работы
- •4 Методические указания к выполнению работы
- •5 Содержание отчета о лабораторной работе
- •Литература
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 |
|
|
||
Поскольку sε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].
Для нее справедливо:
sεn ...ε2ε1Aпр =[sεn ...ε2ε1A; sεn ...ε2ε1B]=[1;X],
т.е. после выполнения произведений ее правый столбец будет содержать решение.
Методом Гаусса можно найти обращенную матрицу. Действительно,
раз sε3ε2ε1A =1, |
|
|
|
sε ε ε = A−1 |
(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.