Решение СЛАУ методом Зейделя - 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");
}

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 4.357 из 5
Похожие ответы