Вы находитесь на странице: 1из 17

ХАРКІВСЬКИЙ НАЦІОНАЛЬНИЙ

УНІВЕРСИТЕТ РАДІОЕЛЕКТРОНІКИ

Кафедра «КІТАМ»

ЗВІТ
з лабораторної роботи № 1
з дисципліни «ЧМ»
на тему «Методи розв'язання систем лінійних алгебраїчних рівнянь»

Виконав Прийняв:
ст. гр. АКТАКІТ-20-3 Доц. кафедри:
Завалюєв.А.О. Сітнікова П.Е.

Харків 2021
Цель занятия
Знакомство с точными и приближенными методами решения систем
линейных алгебраических уравнений.

1.1. Метод Гаусса

Одним из наиболее универсальных и эффективных методов решений систем

линейных алгебраических уравнений является метод Гаусса.

Метод Гаусса – метод последовательного исключения неизвестных –


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

Програма Метода Гауса

#include <iostream>
using namespace std;

int main(int argc, char* argv[])


{
// ввод элементов матрицы n*n+1
int n,m;
cout << "Vvedite razmer matrizi n: ";
cin >> n;
m=n+1;

float array1[n][m];
float array2[n][m];
float y[n];
float a,b;
int i,j,k,l;

for (i = 1; i <= n; i++)


{
for (j = 1; j <= m; j++)
{
cout << "array[" << i << "," << j << "]=" ;
cin >> array1[i][j];
array2[i][j]=array1[i][j]; //копирование для последующей проверки
}
}

// прямой ход
for (k = 1; k < n; k++)
{
// поиск и перестановка ненулевых элементов
while (array1[k][k]==0)
{
l=k;
do
{
l=k+1;
if (l>n) goto end; //выход если в столбце все нули
}
while (array1[l][k]==0);

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


{
b = array1[k][j];
array1[k][j]=array1[l][j];
array1[l][j]= b;
}
}
// приведение к "треугольному" виду
a=array1[k][k];
for (i = k+1; i <= n; i++)
{
b=array1[i][k]/a;
for (j = k; j <= m; j++)
{
array1[i][j]= array1[i][j] - (b*array1[k][j]);
}
}
}

// обратный ход

for (j = n; j >= 1; j--)


{
if (array1[j][j]==0) goto end; // выход если система не имеет решения
a=array1[j][m] / array1[j][j];
b=array1[j][j] / array1[j][j];
for (i = j-1; i >= 1; i--)
{
array1[i][m]= array1[i][m]-(array1[i][j]*a);
array1[i][j]= array1[i][j]-(array1[i][j]*b);
}
}
// cout << "test" << endl;
//for (i = 1; i <= n; i++)
//{
//for (j = 1; j <= m; j++)
//{
//cout << "array[" << i << "," << j << "]=" << array1[i][j]<< endl;
//}
//}
//cout << "reshenie" << endl;

// вычисление определителя основной матрицы

a=1;
for (i = 1; i <= n; i++)
{
a=a*array1[i][i];
}

cout << "det=" << a << endl;

// нормировка

for (i = 1; i <= n; i++)


{

array1[i][m]=array1[i][m]/array1[i][i];
array1[i][i]=array1[i][i]/array1[i][i];

// вывод решения

cout << "reshenie" << endl;

for (i = 1; i <= n; i++)


{
cout << "X[" << i << "]="<< array1[i][m]<< endl;
}

cout << "test" << endl;

// проверка правильности вычисления подстановкой решений в исходную систему

for (i = 1; i <= n; i++)


{
y[i]=0;

for (j = 1; j <= n; j++)


{
y[i]=y[i]+(array2[i][j]*array1[j][m]);

}
}

//если все нули,то решение правильное

for (i = 1; i <= n; i++)


{
cout << "test[" << i << "]="<< array2[i][m]-y[i] << endl;
}
// конец

end: system("pause");
return 0;
}

Ответ

1.2. Метод Зейделя

Код

#include <iostream>

#include <iomanip>

#include <cmath>

#include <windows.h>

using namespace std;

class Matr
{

private:

int size;

double **mas;

double *mas1;

public:

Matr()

size = 0;

mas = NULL;

mas1 = NULL;

Matr(int l)

size = l;

mas = new double*[l];

for (int i = 0; i < l; i++)

mas[i] = new double[l];

mas1 = new double[l];

void Add()

for (int i = 0; i < size; i++)


for (int j = 0; j < size; j++)

cin >> mas[i][j];

for (int i = 0; i < size; i++)

cin >> mas1[i];

void Print()

for (int i = 0; i < size; i++)

for (int j = 0; j < size; j++)

cout << setw(4) << mas[i][j] << " ";

cout << " " << mas1[i] << endl;

void Preob()

double temp = 0;

for (int k = 0; k < size; k++)

{
for (int i = 0; i < size; i++)

temp = mas[i][i] * (-1);

mas1[i] /= temp;

for (int j = 0; j <= size; j++)

mas[i][j] /= temp;

for (int i = 0; i < size; i++)

mas1[i] *= -1;

for (int j = 0; j < size; j++)

mas[i][i] = 0;

double Pogr(double **mas, double epsilon)

double eps = 0; double sum = 0, max = 0;

double norm1 = 0, norm2 = 0;

for (int i = 0; i < size; i++)

{
for (int j = 0; j < i; j++)

sum += fabs(mas[i][j]);

if (sum > norm1) norm1 = sum;

sum = 0;

for (int j = i + 1; j < size; j++)

sum += fabs(mas[i][j]);

if (sum > norm2) norm2 = sum;

sum = 0;

if (norm1 >= 1 || norm2 >= 1)

cerr << "Норма матрицы больше или равна 1." << endl;

Sleep(4000);

exit(1);

eps = ((1 - norm1) / norm2)*epsilon;

return eps;

void Itera(double epsilon)


{

double *x = new double[size];

double *p = new double[size];

double *a = new double[size];

double *E = new double[size];

double per = Pogr(mas, epsilon), max = 0;

for (int i = 0; i < size; i++)

x[i] = mas1[i];

p[i] = 0;

double var = 0;

for (int i = 0; i < size; i++)

var = 0;

for (int k = 0; k < size; k++)

var = mas[i][k] * mas1[k];

x[i] = var;

for (int i = 0; i < size; i++)

p[i] = x[i] + mas1[i];

int counter = 0;

do
{

counter++;

cout << "Итерация № " << counter << endl << endl;

for (int i = 0; i < size; i++)

var = 0;

for (int j = 0; j < i; j++)

var += (mas[i][j] * p[j]);

for (int j = i + 1; j < size; j++)

var += (mas[i][j] * x[j]);

a[i] = var;

x[i] = mas1[i] + a[i];

max = 0;

for (int i = 0; i < size; i++)

E[i] = fabs(x[i] - p[i]);

if (max < E[i]) max = E[i];

p[i] = x[i];

cout << "x" << i + 1 << "=" << x[i] << " " << endl;

cout << endl;

cout << "max =" << max << endl << endl;
} while (max > per);

cout << endl << "Результат: \n\n";

for (int i = 0; i < size; i++)

cout << "x" << i + 1 << "=" << x[i] << " " << endl;

delete[] x;

delete[] p;

delete[] E;

delete[] a;

~Matr()

for (int i = 0; i < size; i++)

delete mas[i];

delete mas;

};

int main()

setlocale(LC_ALL, "rus");

int n; double epsi;

cout << "Введите количество уравнений: ";

cin >> n;

cout << "Введите желаемую точность: ";


cin >> epsi;

Matr a(n);

cout << "Введите матрицу коэффициентов, потом столбец свободных


членов:" << endl;

a.Add();

cout << endl << "Расширенная матрица:" << endl;

a.Print();

a.Preob();

cout << endl << "Преображенная матрица" << endl;

a.Print();

cout << endl;

a.Itera(epsi);

cout << endl;

system("pause");

return 0;

}
Метод простых итераций

#include <iostream>

#include <cmath>

using namespace std;

int main()

double a11 = -19, a12 = 2, a13 = -1, a14 = -8; // матрица

double a21 = 2, a22 = 14, a23 = 0, a24 = -4;

double a31 = 6, a32 = -5, a33 = -20, a34 = -6;

double a41 = -6, a42 = 4, a43 = -2, a44 = 15;

double b1 = 38, b2 = 20, b3 = 52, b4 = 43; // столбец свободных членов


double x1 = 0, x2 = 0, x3 = 0, x4 = 0; // начальное приближение

double x1n, x2n, x3n, x4n;

double eps = 0.0000000000001;

int count;

if ( fabs(a11) > fabs(a12) + fabs(a13) + fabs(a14) &&

fabs(a22) > fabs(a21) + fabs(a23) + fabs(a24) &&

fabs(a33) > fabs(a31) + fabs(a32) + fabs(a34) &&

fabs(a44) > fabs(a41) + fabs(a42) + fabs(a43))

cout << "Diagonal'noe preobladaniye ne narushaetsya" << endl;

else

cout << "Diagonal'noe preobladaniye narushaetsya" << endl;

count = 0;

do

x1n = (b1 - (a12*x2 + a13*x3 + a14*x4))/a11;

x2n = (b2 - (a21*x1 + a23*x3 + a24*x4))/a22;

x3n = (b3 - (a31*x1 + a32*x2 + a34*x4))/a33;

x4n = (b4 - (a41*x1 + a42*x2 + a43*x3))/a44;

count = count + 1;
if(fabs(x1n-x1) < eps &&

fabs(x2n-x2) < eps &&

fabs(x3n-x3) < eps &&

fabs(x4n-x4) < eps) break;

x1 = x1n;

x2 = x2n;

x3 = x3n;

x4 = x4n;

// cout << "x1 = " << x1n << endl << "x2 = " << x2n << endl << "x3 = " << x3n
<< endl << "x4 = " << x4n << endl;

}while(1);

x1 = x1n;

x2 = x2n;

x3 = x3n;

x4 = x4n;

cout << "Kolichestvo iter. = " << count << endl << "x1 = " << x1 << endl

<< "x2 = " << x2 << endl << "x3 = " << x3 << endl << "x4 = " << x4 <<
endl;