Как решить систему уравнений в c
Метод Гаусса для решения систем линейных уравнений
Здесь описан алгоритм решения системы линейных уравнений с помощью так называемого метода Гаусса. Программу вы можете скачать разделе программы. Алгоритм реализован на языке С.
Пусть у нас есть система N линейных уравнений
где xi — неизвестные, aij — коэффициенты при неизвестных, bi — свободные члены в уравнениях, i,j пробегают значения от 1 до N.
Цель задачи — зная aij и bi найти xi.
Суть метода Гаусса состоит в том, что с помощью некоторых операций исходную систему уравнений можно свести к более простой системе. Эта простая система имеет треугольный вид:
Особенность этой системы — в строках с номером i все коэффициенты aij при j
Если мы смогли привести нашу систему уравнений к такому треугольному виду, то решить уравнения уже просто. Из последнего уравнения находим xN= bN / aNN. Дальше подставляем его в предпоследнее уравнение и находим из него xN-1. Подставляем оба найденных решения в следующее с конца уравнение и находим xN-2. И так далее, пока не найдем x1, на чем решение заканчивается. Такая процедура называется обратной прогонкой.
Теперь перейдем к вопросу как же добиться того, чтобы система стала треугольной.
Из линейной алгебры (см. например, Крутицкая Н.И., Тихонравов А.В., Шишкин А.А., Аналитическая геометрия и линейная алгебра с приложениями) известно что если к некоторой строке системы уравнений прибавить любую линейную комбинацию любых других строк этой системы, то решение системы не изменится. Под линейной комбинацией строк понимается сумма строк, каждая из которых у множается на некоторое число (в принципе, любое).
Нужно, чтобы во второй строке получилось уравнение, в которой отсутствует член при x1. Прибавим к этой строке первую строку, умноженную на некоторое число M.
Для того, чтобы член при x1 равнялся нулю, нужно, чтобы M = — a21 / a11. Проделав эту операцию, получившееся уравнение запишем вместо второго и приступим к третьему уравнению. К нему мы прибавим первое уравнение, умноженное на M = — a31 / a11 и тоже получим ноль вместо члена при x1. Такую операцию нужно проделать над всеми остальными уравнениями. В результате получим систему такого вида:
После этого будем избавляться от членов при x2 в третьем, четвертом, N-ом уравнении. Для этого нужно к уравнению с j-м номером прибавить 2-ое уравнение, умноженное на M = — aj2 / a22. Проделав эту операцию над всеми остальными уравнениями, получим систему где нет членов с x2 в уравнениях с номером больше 2.
И так далее. Проделав это для третьего члена, четвертого. до тех пор, пока не кончатся уравнения, получим в итоге систему треугольного вида.
Ниже приведен текст программы.
//HOWTO solve system of linear equations //ax=b //where a[N][N] is square matrix, //b[N] and x[N] are columns //data are stored in input text file: //input file format: //a_11 a_12 a_13. a_1N b_1 //a_21 a_22 a_23. a_2N b_2 //. //a_N1 a_N2 a_N3. a_NN b_N #include #include float **a, *b, *x; int N; char filename[256]; FILE* InFile=NULL; void count_num_lines()< //count number of lines in input file - number of equations int nelf=0; //non empty line flag do< nelf = 0; while(fgetc(InFile)!='\n' && !feof(InFile)) nelf=1; if(nelf) N++; >while(!feof(InFile)); > void freematrix() < //free memory for matrixes int i; for(i=0; idelete [] a; delete [] b; delete [] x; > void allocmatrix() < //allocate memory for matrixes int i,j; x = new float[N]; b = new float[N]; a = new float*[N]; if(x==NULL || b==NULL || a==NULL)< printf("\nNot enough memory to allocate for %d equations.\n", N); exit(-1); >for(i=0; i > for(i=0; i b[i]=0; x[i]=0; > > void readmatrix() < int i=0,j=0; //read matrixes a and b from input file for(i=0; ifscanf(InFile, "%f", &b[i]); > > void printmatrix() < //print matrix "a" int i=0,j=0; printf("\n"); for(i=0; iprintf(" =%f\n", b[i]); > > void testsolve() < //test that ax=b int i=0,j=0; printf("\n"); for(i=0; iprintf("%f\t%f\n", s, b[i]); > > void printresult() < int i=0; printf("\n"); printf("Result\n"); for(i=0; i> void diagonal() < int i, j, k; float temp=0; for(i=0; itemp = b[j]; b[j] = b[i]; b[i] = temp; break; > > > > > void cls() < for(int i=0; ivoid main()< int i=0,j=0, k=0; cls(); do< printf("\nInput filename: "); scanf("%s", filename); InFile = fopen(filename, "rt"); >while(InFile==NULL); count_num_lines(); allocmatrix(); rewind(InFile); //read data from file readmatrix(); //check if there are 0 on main diagonal and exchange rows in that case diagonal(); fclose(InFile); printmatrix(); //process rows for(k=0; k float M = a[i][k] / a[k][k]; for(j=k; j b[i] -= M*b[k]; > > printmatrix(); for(i=N-1; i>=0; i--) < float s = 0; for(j = i; jx[i] = (b[i] - s) / a[i][i]; > InFile = fopen(filename, "rt"); readmatrix(); fclose(InFile); printmatrix(); testsolve(); printresult(); freematrix(); >
Поскольку весь метод уже описан, коротко опишу, как эта программа получает уравнения на вход, что выдает в результате решения.
Чтобы воспользоваться этой программой, нужно запустить скомпилированный исполняемый файл. В первую очередь программа спросит, откуда ей брать коэффициенты для уравнений. Создайте в любом текстовом редакторе (но только не в Word-е а, например в notepad-е) файл, где напишите коэффициенты уравнений построчно через пробел, приблизительно так:
Этот файл необходимо создать в той директории, где лежит программа, иначе она его не найдет. В результате работы программы, она выдаст результат, нечто вроде:
X0 = 3.000000
X1 = 1.000000
X2 = 2.000000
Это и есть решение системы уравнений, т.е. набор неизвестных Х.
- void count_num_lines() — подсчитывает количество уравнений в системе
- void allocmatrix() — выделяет память для массивов для хранения коэффициентов уравнений, свободных членов и решения
- void readmatrix() — прочитывает из файла коэффициенты и свободные члены в массивы
- void printmatrix() — распечатывает систему уравнений
- void diagonal() — делает так, чтобы на главной диагонали не было нулей, чтобы не пришлось однажды делить на ноль в процессе приведения матрицы к треугольному виду
- void testsolve() — подставляет решение в систему и распечатывает рядом то, что получается в левой части уравнения и для сравнения печатает рядом свободные члены, те, что в правой части уравнения; получившиеся два столбца должны совпадать, если уравнения решены правильно
- void printresult() — распечатывает получившийся столбец решений
- void freematrix() — освобождает память, которая была выделена ранее
- void cls() — стирает экран в начале работы программы
- void main() — основная функция из которой последовательно вызываются все вышеперечисленные функции, и проходит процесс приведения системы уравнений к треугольному виду и обратная прогонка.
Программа снабжена комментариями, что облегчает ее понимание.
Как обработать все случаи при решении системы линейных уравнений с двумя неизвестными?
Прошу прощения за мой несколько глупый вопрос, но у меня возникла проблема при подготовке к олимпиаде. Конкретно проблемы вот с этой вот задачей про систему уравнений с двумя неизвестными.
Глохну на 34 тесте.
Казалось бы, все просто:
1 случай (коэффициенты при переменных непропорциональны) Здесь система имеет однозначное решение.
2 случай (коэффициенты при переменных пропорциональны):
Этот случай разбивается на два:
а) коэффициенты при переменных и свободные члены пропорциональны
б) коэффициенты при переменных и свободные члены пропорциональны
Тут просто решений нет, так как прямые параллельны.
Рассматриваю случай а) подробнее, так как требуется выводить разные значения исходя из возможных пар (x, y).
1. Все коэффициенты при переменных равны 0 и свободные члены равны 0 — бесконечное число решений
2. Все коэффициенты при переменных равны 0, но какой-то из свободных членов 0 не равен — решений нет
3. Когда коэффициенты при X равны 0 — тогда у нас есть единственное решение для Y, а X может быть любым
4. Когда коэффициенты при Y равны 0 — тогда у нас есть единственное решение для X, а Y может быть любым
5. Ненулевые коэффициенты, тогда решение у нас представляется в виде Y = k * X + B
Все это я реализовал на C++, код представлен ниже:
int main() < double a, b, c, d, e, f; double x, y; const int no_roots = 0; const int kx_roots = 1; const int one_xy_root = 2; const int one_x = 3; const int one_y = 4; const int inf_roots = 5; cin >> a >> b >> c >> d >> e >> f; double det = a * d - b * c; double det_x = (e * d - b * f); double det_y = (a * f - e * c); bool x_null = a == 0 && c == 0; bool y_null = b == 0 && d == 0; if (det != 0) < x = det_x / det; y = det_y / det; cout else < if (det_x == 0 && det_y == 0) < if (x_null && y_null) < if (e != 0 || f != 0) < cout else < cout > else if (x_null) < if (b != 0) < y = e / b; >else < y = f / d; >cout else if (y_null) < if (a != 0) < x = e / a; >else < x = f / a; >cout else < double bi, k; if (b != 0) < bi = e / b; k = -a / b; >else < bi = f / d; k = -c / d; >cout > else < cout > return 0; >
Что я упускаю из вида? Не могу подобрать такие коэффициенты, на которых программа выдавала бы некорректный ответ.
- Вопрос задан более трёх лет назад
- 1899 просмотров
1 комментарий
Оценить 1 комментарий
Как решить систему уравнений в c
Функции > Решение и оптимизация > Пример. Решение системы линейных уравнений
Пример. Решение системы линейных уравнений
Решите систему n линейных уравнений с n неизвестными с использованием функции lsolve или с помощью блоков решения
Использование lsolve
1. Предположим, что имеется следующий набор уравнений (определенных с помощью оператора «равно»):

2. Задайте несингулярную матрицу, соответствующую данной системе уравнений:

3. Задайте вектор из констант, соответствующий данной системе уравнений.

4. Используйте функцию lsolve для поиска решения:


Использование блоков решения
Вышеприведенную систему уравнений также можно решить с помощью блока решения.
Если представить систему в виде матрицы, умноженной на неизвестный вектор X, то необходимо найти решение одновременно для всех переменных в векторе. В такой формулировке ни один из элементов вектора нельзя представить в виде константы.
1. Задайте вектор начальных приближений X:


2. Вставьте блок решения, а затем используйте функцию find для решения заданной системы уравнений:

В вектор начальных приближений X должен быть определен выше и за пределами блока решения.
Блоки решения — решения для матриц
1. Задайте набор алгебраических уравнений Риккати (из теории систем и управления):



2. Задайте матрицу начальных приближений как единичную матрицу:

3. Используйте функцию find для решения заданного набора уравнений:

Единицы измерения в блоках решения
1. Задайте V1 , V2 и V3 значение 1 вольт:



2. Задайте и решите систему уравнений с тремя неизвестными:
Системы уравнений с двумя переменными, способы решения

Уравнениями называются математические равенства разной степени сложности, в которых одна или несколько величин неизвестны. Значения всех переменных нужно найти таким образом, чтобы в результате их постановки в первоначальное уравнение получилось верное числовое равенство.
Под системой уравнений понимается условие, которое заключается в одновременном выполнении нескольких уравнений, логически связанных между собой, относительно одной или нескольких переменных. Рассмотрим все варианты решения систему уравнений с двумя переменными.
Основные виды систем уравнений
В математике насчитывается достаточно много видов систем уравнений. Для более удобного их изучения и нахождения решений их разделяют на несколько групп с определёнными характеристиками.
Классификация помогает рассматривать системы уравнений разных видов. Первый вариант – это классифицирование по количеству уравнений в системе. Если оно всего одно, то его называют обычным уравнением. Если уравнений несколько, тогда речь идет о системе.
Отличительным критерием для другого вида классификации является количество переменных. Если переменная одна, значит это уравнение с одной неизвестной, если их две – то с двумя неизвестными и т.д.
Основные способы решения системы уравнений
Для того чтобы решить систему уравнений с двумя переменными, необходимо определить значения пары переменных, которые при подстановке в каждое из уравнений обратят их в верные числовые неравенства. Если удалось вычислить эти значения правильно, то они и будут являться решением для всех уравнений рассматриваемой системы.
В алгебре некоторые системы уравнений могут вовсе не иметь правильных решений или наоборот их может быть бесконечное множество. Убедиться в этом можно, если заняться углубленным изучением данной тематики. В итоге можно прийти к выводу, что системы представляют собой множества решений всех ее уравнений.
Рассмотрим основные способы решения систем с двумя неизвестными:
- способ подстановки;
- графический способ;
- способ сложения;
- способ введения новых переменных.
Чтобы подробно описать принцип решения на примере первых трех способов, будем рассматривать системы линейных уравнений с двумя неизвестными.
Нет времени решать самому?