Ошибка в программе для решения СЛАУ методом Гаусса - C (СИ)
Формулировка задачи:
Здравствуйте помогите пожалуйста!
Не могу найти ошибку в программе
Алгоритм такой: среди элементов первого столбца матрицы выбираю ненулевой, перемещаю его на крайнее верхнее положение перестановкой строк и вычитаю получившуюся после перестановки первую строку из остальных строк, домножив её на величину, равную отношению первого элемента каждой из этих строк к первому элементу первой строки, обнуляя тем самым столбец под ним.
При решении СЛАУ 3-го порядка:
1 2 3 3
3 5 7 0
1 3 4 1
матрица приведенная к треугольному виду:
1 2 3 3
0 1 2 9
0 0 1 11
корни -14; -13; 11 все в порядке
а если случай множества решений
исходная матрица:
1 -2 0 1 -3
3 -1 -3 0 1
2 1 -2 -1 4
1 3 -2 -2 7
Матрица приведенная к треугольному виду:
1 -2 0 1 -3
0 1 -0.6 -0.6 2
0 0 1 0 0
0 0 0 1 0
почему то в нижних двух строках матрицы 1-цы хотя должны быть нули
//Решение системы линейных уравнений методом Гаусса #include <stdio.h> #include <conio.h> #include <math.h> #include <windows.h> #define N 10 void main() { SetConsoleCP (1251);//для правильного отображения русского шрифта в консоли SetConsoleOutputCP (1251);//для правильного отображения русского шрифта в консоли system("cls");//производит очистку экрана float t, a[N][N + 1], x[N];//x[N]-корни системы; int i, j, k, n, count = 0;//j - номер строки, i - номер столбца; bool f = false; do { printf("Введите размерность матрицы:\n"); scanf("%d", &n); if(n>N) printf("Слишком большое число уравнений. Повторите ввод.\n"); else printf("N = %d\n",n); } while(n>N); printf("Введите СЛАУ:\n");//ввод исходных данных for(j = 0; j < n; j++) for(i = 0; i < n + 1; i++) { printf("a[%d][%d] = ",j,i); scanf("%f", &a[j][i]); count++; if(count == (n + 1)) printf("\n",count=0); } system("cls"); printf("Исходная матрица:\n");//вывод данных на экран for(j = 0; j < n; j++) { for(i = 0; i < n + 1; i++) printf("%6.3f\t",a[j][i]); printf("\n"); } //проверка на бесконечное множество решений for(j = 0; j < n; j++)//проверка системы уравнений, а[0][0] не должен быть 0 { if(fabs(a[j][j]) < 0.0001) { f = true; } else if(a[j][j] == 0) { k = j;//запоминаем адрес строки; while((a[k+1][i] == 0) && (k < n))//если 0 изменяем порядок уравнений k++; if(a[k+1][i] != 0) { for(i = 0; i < n + 1; i++) { t = a[j][i]; a[j][i] = a[k+1][i]; a[k+1][i] = t; } //вывод полученной матрицы for(j = 0; j < n; j++) { for(i = 0; i < n + 1; i++) printf("%6.3f\t",a[j][i]); printf("\n"); } } else { f = true;//если по диаганали нули } } } //прямой ход for(k = 0; k < n; k++) { for(j = n; j >= k; j--) a[k][j] = a[k][j]/a[k][k];//делим на коэффиц. a[1][1],a[2][2] и т.д. for(i = k + 1; i < n; i++) for(j = n; j >= k; j--) a[i][j] = a[i][j] - a[i][k]*a[k][j];//вычитаем из 2 ур-ия 1-ое умнож. на коэфф. и т.д. } /* //проверка системы for( j = 0; j < n; j++ ) { count = 0; for(i = 0; i < n; i++) { if(a[j][i] == 0) count++; printf("кол-во нулей: %d",); if(count == (n - 1) && a[j][n] == 0)//если коэфф. в строке = 0 и своб. член = 0 printf("СЛАУ не имеет решений\n"); else if (count == (n - 1) && a[j][n] != 0)//если коэфф. в строке = 0 и своб. член не равен 0 f = true;// имеет множество решений } } */ //обратный ход for(i = 0; i < n; i++) x[i] = a[i][n]; for(i = n-2; i >= 0; i--) for(j = i+1; j < n; j++) x[i] = x[i] - x[j]*a[i][j];//находим корни if(f == false) { //вывод матрицы треугольного вида printf("Матрица приведенная к треугольному виду:\n"); for(j = 0; j < n; j++) { for(i = 0; i < n + 1; i++) printf("%6.3f\t",a[j][i]); printf("\n"); } //вывод решения printf("Корни СЛАУ:\n"); for(i = 0; i < n; i++) printf("x[%d] = %6.3f\n",i,x[i]); } else printf("Система имеет множество решений\n"); }
Решение задачи: «Ошибка в программе для решения СЛАУ методом Гаусса»
textual
Листинг программы
//Решение системы линейных уравнений методом Гаусса с выбором главного элемента по столбцу #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <math.h> #include <windows.h> #define N 10 int main(void) { SetConsoleCP (1251);//для правильного отображения русского шрифта в консоли SetConsoleOutputCP (1251);//для правильного отображения русского шрифта в консоли system("cls");//производит очистку экрана float t, a[N][N + 1], x[N];//x[N]-корни системы; int i, j, k, n, j_max, count = 0;//j - номер строки, i - номер столбца; //ввод размерности матрицы do { printf("Введите размерность матрицы:\n"); scanf("%d", &n); if(n>N) printf("Слишком большое число уравнений. Повторите ввод.\n"); else printf("N = %d\n",n); } while(n>N); //ввод СЛАУ printf("Введите СЛАУ:\n");//ввод исходных данных for(j = 0; j < n; j++) for(i = 0; i < n + 1; i++) { printf("a[%d][%d] = ",j,i); scanf("%f", &a[j][i]); count++; if(count == (n + 1)) printf("\n",count=0); } system("cls");//очистка экрана //вывод данных на экран printf("Исходная матрица:\n"); for(j = 0; j < n; j++) { for(i = 0; i < n + 1; i++) printf("%6.2f\t",a[j][i]); printf("\n"); } //прямой ход for( k = 0; k < n; k++ ) { j_max = k; for( j = k; j < n; j++) if ( fabs(a[j_max][k] ) < fabs (a[j][k]) ) j_max = j; //переставляем строки for(i = 0; i < n + 1; i++) { t = a[k][i]; a[k][i] = a[j_max][i]; a[j_max][i] = t; } //вывод полученной матрицы printf("матрица после %d преобразований\n",k+1); for(j = 0; j < n; j++) { for(i = 0; i < n + 1; i++) printf("%6.2f\t",a[j][i]); printf("\n"); } //если максимальный элемент нулевой if(a[j_max][k] == 0) { count = 0; for(i = 0; i < n; i++) { if(a[k][i] == 0) count++; printf("кол-во нулей: %d\n",count); if(count == n && a[k][n + 1] == 0)//если коэфф. в строке = 0 и своб. член = 0 { printf("СЛАУ имеет множество решений\n"); return(0); } else if (count == n && a[k][n + 1] != 0)//если коэфф. в строке = 0 и своб. член не равен 0 { printf("СЛАУ не имеет решений\n"); return(0); } } } //выполнение вычислений for(j = n; j >= k; j--) a[k][j] = a[k][j]/a[k][k];//делим на коэффиц. a[1][1],a[2][2] и т.д. for(i = k + 1; i < n; i++) for(j = n; j >= k; j--) a[i][j] = a[i][j] - a[i][k]*a[k][j];//вычитаем из 2 ур-ия 1-ое умнож. на коэфф. и т.д. */ } //вывод матрицы треугольного вида printf("Матрица приведенная к треугольному виду:\n"); for(j = 0; j < n; j++) { for(i = 0; i < n + 1; i++) printf("%6.2f\t",a[j][i]); printf("\n"); } //обратный ход for(i = 0; i < n; i++) x[i] = a[i][n]; for(i = n-2; i >= 0; i--) for(j = i+1; j < n; j++) x[i] = x[i] - x[j]*a[i][j];//находим корни //вывод решения printf("Корни СЛАУ:\n"); for(i = 0; i < n; i++) printf("x[%d] = %6.2f\n",i,x[i]); }
Объяснение кода листинга программы
В коде представлена реализация решения системы линейных уравнений методом Гаусса с выбором главного элемента по столбцу.
- Ввод размерности матрицы:
В этой части кода пользователь вводит размерность матрицы, которая представляет собой количество уравнений в системе. Введенное значение сохраняется в переменной
n
. - Ввод СЛАУ:
Здесь пользователю предлагается ввести СЛАУ, то есть исходные данные системы линейных уравнений. Код просит ввести все элементы матрицы
a[j][i]
и сохраняет их в соответствующих переменных. - Прямой ход:
Этот блок кода представляет собой прямой ход метода Гаусса. Он начинается с инициализации переменной
k
равной 0 и продолжается до тех пор, покаk
меньшеn
. В каждой итерации код находит максимальное значение в текущем столбце матрицы и переставляет строки так, чтобы главный элемент был на позицииk
. Затем код выполняет соответствующие вычисления для преобразования матрицы. - Матрица приведенная к треугольному виду:
Здесь выводится матрица
a[j][i]
, преобразованная в треугольный вид. - Обратный ход:
Этот блок кода представляет собой обратный ход метода Гаусса. Он начинается с инициализации всех переменных
x[i]
равнымиa[i][n]
. Затем, двигаясь отn-1
к 0, для каждогоi
вычисляется значениеx[i]
как остаток от деленияa[i][j]
наa[j][j]
. - Вывод решения:
В этой части кода выводятся значения корней системы
x[i]
на экран. Код не содержит ошибок и должен корректно работать для любой размерности матрицы и СЛАУ.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д