МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ «ЛЬВІВСЬКА ПОЛІТЕХНІКА»
ІКТА
Кафедра ЗІ
Звіт про виконання
лабораторної роботи №3
з курсу: «Комп’ютерні методи дослідження інформаційних процесів та систем»
на тему: «ІТЕРАЦІЙНІ МЕТОДИ РОЗВ’ЯЗУВАННЯ СИСТЕМ
ЛІНІЙНИХ АЛГЕБРАЇЧНИХ РІВНЯНЬ»
Львів 2015
Мета роботи: Ознайомлення з ітераційними методами розв’язування систем лінійних алгебраїчних рівнянь.
Короткі теоретичні відомості :
Метод Зейделя
Задано систему лінійних алгебраїчних рівнянь, що зведена до нормального вигляду.
.
Тоді за методом Зейделя, вибираючи вектор початкових наближень
(як правило, це стовпець вільних членів ), уточнення значень невідомих проводять наступним чином:
1) перше наближення:
2) k + 1 наближення
k = 0, 1, 2, … .
Таким чином ітераційний процес подібний до методу простих ітерацій, однак уточнені значення одразу ж підставляються в наступні рівняння:
– формула методу Зейделя.
Іншими словами, метод Зейделя відрізняється від методу простої ітерації тим, що при обчисленні на “k+1”-му кроці враховуються значення , , , обчислені на цьому самому кроці.
З метою економії пам’яті при програмуванні методу Зейделя недоцільно напряму застосовувати подану формулу методу. На відміну від методу простої ітерації в методі Зейделя немає необхідності зберігати в пам’яті повністю вектор попередніх наближень розв’язку. Можна застосовувати один вектор, в якому будуть зберігатися останні наближення розв’язків. При цьому для контролю умови завершення ітераційного процесу по кожному з розв’язків можна застосовувати одну й ту саму допоміжну змінну для тимчасового зберігання попереднього наближення чергового розв’язку.
Слід сподіватись, що ітерації за методом Зейделя дадуть при тому ж числі кроків більш точні результати, ніж за методом простої ітерації. Або така ж точність буде досягнута за менше число кроків, оскільки чергові значення невідомих визначаються тут більш точно ітераційний процес припиняється.
Завдання до лабораторної роботи:
Розв’язати систему лінійних алгебраїчних рівнянь методами простої ітерації або Зейделя.
,
Блок-схема алгоритму програми:
початок
створення масивів А, а, х, b
заповнення масивів А та b
Масиви А та b
Console.ReadLine();
Console.Clear();
система рівнянь
i=0,n
j=0,n
ні так
i=j b[i] = b[i] / a[i, i];
A[i, j] = -a[i, j] / a[i, i]; A[i, j] = 0;
початкове наближення
i=0,n
x[i] = b[i];
масив початкових наближень
v=0;
1
1
while (Math.Abs(x[0]-f)>E)
f=x[0];
v++
i=0,n
S1 = 0;
S2 = 0;
j=0,i
S1 += A[i, j] * x[j];
j=i,n
S2 += A[i, j] * x[j];
x[i] = b[i] + S1 + S2;
x[i]
кінець
Список ідентифікаторів констант, змінних, процедур і функцій:
main – головна функція
printf, scanf – функції вводу-виводу даних
for – оператор циклу;
a – матриця коефіцієнтів
A – матриця а, зведена до нормального вигляду
x – стовпцева матриця розв’язків
Остаточний текст програми мовою С:
// ConsoleApplication6.cpp : Defines the entry point for the console application.
//
// ConsoleApplication8.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include<conio.h>
#include<stdio.h>
#include<math.h>
#define n 4
#define E 0.0001
void main()
{
int i, j;
double k, p, S, t, a[n][n], A[n][n], b[n], x[n], z[n], suma;
printf("k="); scanf_s("%lf", &k);
S = k*0.2;
printf("p="); scanf_s("%lf", &p);
t = p*0.2;
a[0][0] = 13.3; a[0][1] = 12.62 + S; a[0][2] = 4.1; a[0][3] = 1.9;
a[1][0] = 3.92; a[1][1] = 8.45; a[1][2] = 1.78 - S; a[1][3] = 1.4;
a[2][0] = 3.77; a[2][1] = 1.21 + S; a[2][2] = 8.04; a[2][3] = 0.28;
a[3][0] = 2.21; a[3][1] = 3.65 - S; a[3][2] = 1.69; a[3][3] = 9.99;
b[0] = -10.55 + t; b[1] = 12.21; b[2] = 15.45 - t; b[3] = -8.35;
for (i = 0; i<n; i++)
{
for (j = 0; j<n; j++)
printf("%lf ", a[i][j]);
printf("%lf\n", b[i]);
}
for (i = 0; i<n; i++)
{
b[i] /= a[i][i];
for (j = 0; j<n; j++)
if (i != j) A[i][j] = a[i][j] / (-a[i][i]);
else A[i][j] = 0.0;
printf("\n");
}
for (i = 0; i<n; i++)
{
for (j = 0; j<n; j++) printf("%lf ", A[i][j]);
printf("%lf\n", b[i]);
}
for (i = 0; i<n; i++)
{
z[i] = x[i]; x[i] = b[i];
}
M1: for (i = 0; i<n; i++)
{
z[i] = x[i];
}
for (i = 0; i<n; i++)
{
suma = 0.0;
for (j = 0; j<n; j++)
suma += A[i][j] * x[j];
x[i] = b[i] + suma;
}
for (i = 0; i<n; i++)
if (fabs(x[i] - z[i]) >= E) goto M1;
printf("\n \n Koreni: \n");
for (i = 0; i<n; i++) printf(" x%d=%lf\n ", i + 1, x[i]);
scanf_s("%lf", &p);
}
Результат виконання програми:
Висновок:
Виконавши лабораторну роботу, я ознайомилася з ітераційними методами розв’язування систем лінійних алгебраїчних рівнянь. В даній роботі я використовувала простий метод ітерації.