Решение СЛАУ методом Зейделя - C (СИ)
Формулировка задачи:
Народ, я написал прогу, которая решает СЛАУ методом Зейделя. Но проблема в том, что входная матрица коэффициентов пред x, должна иметь диагональное преобладание. Мне нужно как-то проверить имеет ли система решения, и приводится ли матрица коэффициентов к диагональному виду? А если приводится, то как?
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <locale.h>
main()
{
double maxd, maxdp=0, *B, *X, *d, **A, ESP;
int i, j, n;
//Задаем количество строк СЛАУ
scanf("%d", &n);
//Создаем матрицу коэффициентов перед Х и результирующую матрицу
B = (double*)malloc(n*sizeof(double));
X = (double*)malloc(n*sizeof(double));
d = (double*)malloc(n*sizeof(double));
A = (double**)malloc(n*sizeof(double*));
for (i = 0; i<n; ++i)
{
B[i] = 0; X[i] = 0; d[i] = 0;
A[i] = (double*)malloc(n*sizeof(double));
for (j = 0; j<n; ++j)
{
A[i][j] = 0;
}
}
//Вводим значения матрицыкоэффициентов перед Х
for (i = 0; i<n; ++i)
{
for (j = 0; j<n; ++j)
{
printf("A[%d][%d]=", i, j);
scanf("%lf", &A[i][j]);
}
printf("\n");
}
//Вводим значения результирующей матрицы
for (i = 0; i<n; ++i)
{
printf("B[%d]=", i);
scanf("%lf", &B[i]);
}
//Водим значение погрешности
scanf("%lf", &ESP);
//Производится решение методом Зейделя
do
{
for (i = 0; i < n; ++i)
{
d[i] = X[i];
X[i] = B[i];
for (j = 0; j < n; ++j)
{
if (i != j)
{
X[i] -= A[i][j] * X[j];
}
}
X[i] = X[i]/A[i][i];
d[i] = fabs(d[i] - X[i]);
}
maxd = d[0];
for (i = 1; i<n; ++i)
{
if (d[i]>maxd) maxd = d[i];
}
if (maxdp == 0)
{
maxdp = maxd;
continue;
}
else
{
if (maxdp - maxd<0)
{
break;
}
else
{
maxdp = maxd;
}
}
}
while (maxd > ESP);
//Вывод ответа
for (i = 0; i < n; ++i)
{
printf("X[%d]=%lf ", i, X[i]);
}
system("pause");
}Решение задачи: «Решение СЛАУ методом Зейделя»
textual
Листинг программы
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<locale.h>
#include<Windows.h>
#include<conio.h>
#include <math.h>
#include <stdlib.h>
main()
{
double maxd, maxdp = 0, *B, *X, *d, **A, ESP, k, sum_kv = 0;
int i, j, n, y=-1;
char r;
FILE *f;
setlocale(LC_ALL, "RUS");
printf("Справка:\n");
printf("Система линейных алгебраических уравнений как правило имеет вид:\n");
printf("A[1][1]X[1]+A[1][2]X[2]+...+A[1][n]X[n]=B[1]\n");
printf("A[2][1]X[1]+A[2][2]X[2]+...+A[2][n]X[n]=B[2]\n");
printf(" . . . \n");
printf("A[n][1]X[1]+A[n][2]X[2]+...+A[n][n]X[n]=B[n]\n\n");
printf("Данная программа потребует ввод матрицы коэффициентов перед X,\nкоторая выглядит следующим образом:\n");
printf(" _ _\n");
printf("| A[1][1] A[1][2] ... A[1][n] |\n");
printf("| A[2][1] A[2][2] ... A[2][n] |\n");
printf("| . . . |\n");
printf("|_A[n][1] A[n][2] ... A[n][n]_|\n\n");
printf("А результирующая матрица в данной программе имеет вид:\n");
printf(" _ _\n");
printf("| B[1] |\n");
printf("| B[2] |\n");
printf("| ... |\n");
printf("|_B[n]_|\n\n");
while (1)
{
setlocale(LC_ALL, "RUS");
printf("|<br>MENU<br>|\n");
printf("|1. Ввод данных с клавиатуры<br>|\n");
printf("|2. Использовать данные из файла<br>|\n");
printf("|3. Использовать генерацию данных<br>|\n");
printf("|4. ВЫХОД<br>|\n");
printf("\nВыберете пункт меню\n");
setlocale(LC_ALL, "C");
r = _getch();
while ((r < 49) || (r > 52))
{
setlocale(LC_ALL, "RUS");
printf("\n\nОшибка ввода. Повторите попытку.\n");
setlocale(LC_ALL, "C");
r = _getch();
}
switch (r)
{
case '1':
//Задаем количество строк СЛАУ
setlocale(LC_ALL, "RUS");
printf("Задайте количество строк:\n");
setlocale(LC_ALL, "C");
scanf("%d", &n);
//Выделяем память под матрицы
B = (double*)malloc(n*sizeof(double));
X = (double*)malloc(n*sizeof(double));
d = (double*)malloc(n*sizeof(double));
A = (double**)malloc(n*sizeof(double*));
for (i = 0; i < n; ++i)
{
B[i] = 0; X[i] = 0; d[i] = 0;
A[i] = (double*)malloc(n*sizeof(double));
for (j = 0; j < n; ++j)
{
A[i][j] = 0;
}
}
setlocale(LC_ALL, "RUS");
printf("\nПострочно введите значения матрицы коэффициентов перед x\n(при i=j A[i][j] не равно 0).\n");
setlocale(LC_ALL, "C");
//Вводим значения матрицыкоэффициентов перед Х
for (i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
{
printf("A[%d][%d]=", i + 1, j + 1);
scanf("%lf", &A[i][j]);
if ((i == j) && (A[i][j] == 0))
{
setlocale(LC_ALL, "RUS");
printf("\nОшибка ввода!\nВведите 1, чтобы задать другие параметры или 2, чтобы выйти.\n");
setlocale(LC_ALL, "C");
scanf("%d", &y);
if (y == 2) exit(0);
if (y == 1) break;
}
}
printf("\n");
if (y == 1) break;
}
if (y == -1)
{
setlocale(LC_ALL, "RUS");
printf("Введите значения результирующей матрицы.\n");
setlocale(LC_ALL, "C");
//Вводим значения результирующей матрицы
for (i = 0; i < n; ++i)
{
printf("B[%d]=", i + 1);
scanf("%lf", &B[i]);
}
setlocale(LC_ALL, "RUS");
printf("\nМатрица коэффициентов перед х имеет вид:\n");
setlocale(LC_ALL, "C");
for (i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
{
printf("%lf ", A[i][j]);
}
printf("\n");
}
setlocale(LC_ALL, "RUS");
printf("\nРезультирующая матрица имеет вид:\n");
setlocale(LC_ALL, "C");
for (i = 0; i < n; ++i)
{
printf("%lf\n", B[i]);
}
//Выполняем проверку
for (i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
{
if (i != j)
{
k = -A[i][j] / A[i][i];
sum_kv += k*k;
}
else
{
sum_kv += 0;
}
}
}
sum_kv = sqrt(sum_kv);
if (sum_kv >= 1)
{
setlocale(LC_ALL, "RUS");
printf("\nПоследовательность не является сходящейся!\nВведите 1, чтобы задать другие параметры или 2, чтобы выйти.\n");
setlocale(LC_ALL, "C");
scanf("%d", &y);
}
}
if (y == 2) exit(0);
if (y == -1)
{
//Водим значение погрешности
setlocale(LC_ALL, "RUS");
printf("\nВведите значение погрешности:\n");
setlocale(LC_ALL, "C");
scanf("%lf", &ESP);
}
break;
case '2':
f = fopen("kursovaya.txt", "r+");
fscanf(f, "%d", &n);
B = (double*)malloc(n*sizeof(double));
X = (double*)malloc(n*sizeof(double));
d = (double*)malloc(n*sizeof(double));
A = (double**)malloc(n*sizeof(double*));
for (i = 0; i < n; ++i)
{
B[i] = 0; X[i] = 0; d[i] = 0;
A[i] = (double*)malloc(n*sizeof(double));
for (j = 0; j < n; ++j)
{
A[i][j] = 0;
}
}
for (i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
{
fscanf(f, "%lf", &A[i][j]);
}
fscanf(f, "%lf", &B[i]);
}
fscanf(f, "%lf", &ESP);
fclose(f);
for (i = 0; i < n; ++i)
{
if (A[i][i] == 0)
{
setlocale(LC_ALL, "RUS");
printf("\nФайл заполнен не верно!\nРекомендация: Введите 1, чтобы снова воспользоваться меню\nи задать значения вручную.\nИли введите 2, чтобы выйти.\n");
setlocale(LC_ALL, "C");
if (y == 2) exit(0);
if (y == 1) break;
}
}
if (y == -1)
{
setlocale(LC_ALL, "RUS");
printf("\nМатрица коэффициентов перед х имеет вид:\n");
setlocale(LC_ALL, "C");
for (i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
{
printf("%lf ", A[i][j]);
}
printf("\n");
}
setlocale(LC_ALL, "RUS");
printf("\nРезультирующая матрица имеет вид:\n");
setlocale(LC_ALL, "C");
for (i = 0; i < n; ++i)
{
printf("%lf\n", B[i]);
}
//Выполняем проверку
for (i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
{
if (i != j)
{
k = -A[i][j] / A[i][i];
sum_kv += k*k;
}
else
{
sum_kv += 0;
}
}
}
sum_kv = sqrt(sum_kv);
if (sum_kv >= 1)
{
setlocale(LC_ALL, "RUS");
printf("\nПоследовательность не является сходящейся!\nВведите 1, чтобы задать другие параметры или 2, чтобы выйти.\n");
setlocale(LC_ALL, "C");
scanf("%d", &y);
}
}
if (y == 2) exit(0);
break;
case '3':
n = rand() % 2 + 2;
B = (double*)malloc(n*sizeof(double));
X = (double*)malloc(n*sizeof(double));
d = (double*)malloc(n*sizeof(double));
A = (double**)malloc(n*sizeof(double*));
for (i = 0; i < n; ++i)
{
B[i] = 0; X[i] = 0; d[i] = 0;
A[i] = (double*)malloc(n*sizeof(double));
for (j = 0; j < n; ++j)
{
A[i][j] = 0;
}
}
for (i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
{
A[i][j] = rand() % 20 - 10;
}
B[i] = rand() % 20 - 10;
}
ESP = rand() % 100 / 10000;
for (i = 0; i < n; ++i)
{
if (A[i][i] == 0)
{
setlocale(LC_ALL, "RUS");
printf("\nЗначения сгенерированы не верно!\nРекомендация: Введите 1, чтобы снова воспользоваться меню\nи задать значения вручную.\nИли введите 2, чтобы выйти.\n");
setlocale(LC_ALL, "C");
if (y == 2) exit(0);
if (y == 1) break;
}
}
if (y == -1)
{
setlocale(LC_ALL, "RUS");
printf("\nМатрица коэффициентов перед х имеет вид:\n");
setlocale(LC_ALL, "C");
for (i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
{
printf("%lf ", A[i][j]);
}
printf("\n");
}
setlocale(LC_ALL, "RUS");
printf("\nРезультирующая матрица имеет вид:\n");
setlocale(LC_ALL, "C");
for (i = 0; i < n; ++i)
{
printf("%lf\n", B[i]);
}
//Выполняем проверку
for (i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
{
if (i != j)
{
k = -A[i][j] / A[i][i];
sum_kv += k*k;
}
else
{
sum_kv += 0;
}
}
}
sum_kv = sqrt(sum_kv);
if (sum_kv >= 1)
{
setlocale(LC_ALL, "RUS");
printf("\nПоследовательность не является сходящейся!\nРекомендация: Введите 1, чтобы снова воспользоваться меню\nи задать значения вручную.\nИли введите 2, чтобы выйти.\n");
setlocale(LC_ALL, "C");
scanf("%d", &y);
}
}
if (y == 2) exit(0);
break;
case '4':
exit(0);
break;
}
if (y == -1) break;
else
{
free(X);
free(B);
free(d);
for (i = 0; i < n; ++i)
{
free(A[i]);
}
free(A);
y = -1;
system("cls");
}
}
//Производится решение методом Зейделя
do
{
for (i = 0; i < n; ++i)
{
d[i] = X[i];
X[i] = B[i];
for (j = 0; j < n; ++j)
{
if (i != j)
{
X[i] -= A[i][j] * X[j];
}
}
X[i] = X[i]/A[i][i];
d[i] = fabs(d[i] - X[i]);
}
maxd = d[0];
for (i = 1; i<n; ++i)
{
if (d[i]>maxd) maxd = d[i];
}
}
while (maxd > ESP);
//Вывод ответа
setlocale(LC_ALL, "RUS");
printf("\nКорнями данной системы линейных алгебраических уравнений являются:\n");
setlocale(LC_ALL, "C");
for (i = 0; i < n; ++i)
{
printf("X[%d]=%lf\n", i + 1, X[i]);
}
free(B);
free(X);
free(d);
for (i = 0; i < n; ++i)
{
free(A[i]);
}
free(A);
system("pause");
}