Решение СЛАУ методом Зейделя - 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"); }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д