Методы Гаусса и Крамера[c++] Как-то на кряклабе нашёл несколько примеров по решению систем линейных уравнений этим методом. Но 404. . Решил написать сам. Для привидения матрицы к главному ступенчатому виду использовал метод ведущего элемента(для машины он проще чем сначала получение верхне треугольной матрицы , а потом самого вида.) Т.к. часто попадаются "плохие" числа и приходится работать с дробями, то написал класс для дробей, перегрузил операторы *, / , + , - . Сделал функции 1, 2 и 3 элементарных преобразований. Также есть алгоритм оброботки нулевых эллемтов на главной диагонале.Для этого написал отдельно класс для матриц. Ввод матрицы осуществляется в самой программе. Программа таже показывает пошагово значения матриц. Приводить весь алгоритм небуду, т.к. он очень большой. Исходники и откомпиленная прога ниже(вместе с Крамером): http://slil.ru/25072002 http://ifolder.ru/4038710 http://rapidshare.com/files/68056699/Gauss_Kramer.rar.html
Ты бы лучше за свой ужасный С++ извинился. Что уж говорить, если ты не знаешь как через cout переменную вывести. Использовать код вида: Code: printf("Insert %d element of second matrix:",x); cin>>temp; cout<<"\r\n"; это норм по твоему? Но больше всего конечно порадовало подключение windows.h ради функции ExitProcess. Ты только не подумай, что я опять наезжаю на тебя или еще чего.
Ni0x, ты че, это кроссплатформеный Опен-Сурс от Кузьмича. А вот это вообще будет висеть у меня на стенке в корридоре Ещё. Крутой деструктор ))))) Ну и самый прикол на всякий случай кодер решил везде написать (по всему тексту прямо) "drob::" чтоб вдруг что....гыгы
не удивительно, шо у меня ошибки при компеляци)) кстате я метод гаус на 5 сдал!!! имея 3 по математике в школе по жизни
Ну и какие-же это ошибки? Так: Code: printf("Insert %d element of second matrix:",x); Намного удобнее и короче, чем: Code: cout<<"Insert "<<x<< " element of second matrix:"; Неправдали?
Большое спасибо за критику. Учёл. Улучшил Гаусса, добавил обработку нулевых элементов на главной диагонале. Вот, ещё написал метод Крамера с рекурсивным вычислением определителя. Code: #include <tchar.h> #include <iostream> using namespace std; /*функция возведения в определённую степень числа -1*/ int mypow(int x){ int y=1; for(int z=1;z<=x;z++){ y*=-1; } return y; } /*класс матрица*/ class matrix{ public: /*Конструктор: все элементы 0, размерность 0 */ matrix(){ size=0; for(int x=0;x<=100;x++) for(int y=0;y<=100;y++) m[x][y]; } /*Рекурсивная функция вычисления определителя */ int GetDet(){ int result=0; if(size==1){ //Если у матрицы размерность 2(математическая, С`шная 1), то вычисляем определитель return m[0][0]*m[1][1]-m[0][1]*m[1][0]; } else{ /*Вычисляем определитель путём вычёркивания строк и столбцов. Берём элементы из первой строки. */ for(int x=0;x<=size;x++){ result+= mypow(x+2)*m[0][x]*(GetNew(x)).GetDet(); //рекурсия... } return result; } } /*Функия получения новой матрицы из старой, путём вычёркивания первой(нулевой) строки и х`овой колонки*/ matrix GetNew(int st){ matrix result; int z=0; result.size=size-1; for(int x=1;x<=size;x++){ for(int y=0;y<=size;y++){ if(y!=st){ result.m[x-1][z]=m[x][y]; z++; } } z=0; } return result; } /*Функция вывода на экран квадратной матрицы*/ void echo(void){ for(int x=0;x<=size;x++){ for(int y=0; y<=size;y++){ cout<<m[x][y]<<" "; } cout<<"\r\n"; } } /*Функция вывода на экран матрицы-столбца */ void echoEx(void){ for(int x=0;x<=size;x++){ cout<<m[x][0]<<"\r\n"; } } /*Функция установки размерности матрицы*/ inline void SetSize(int r){ size=r; } /*Функция установки значения элемента*/ inline void SetValue(int value, int x , int y){ m[x][y]=value; } /*Функция замены колонки на матриуц-столбец*/ inline void SetColumn(int column , matrix source){ for(int x=0;x<=size;x++){ m[x][column]=source.m[x][0]; } } private: int m[100][100]; //сама матрица int size; //размерность }; int _tmain(int argc, _TCHAR* argv[]) { matrix first,second,temp; //наши матрицы int element,size,maindet; //необходимые переменные bool c=1; //для цикла cout<<"The Kramer method for the system of linear equations. By Ky3bMu4 (c) 2007.\r\n\r\n"; while(c){ cout<<"\r\nInsert size of matrix:"; /*тут небольшая неровность: в математике матрица начинается с 1 столбцы, а в С - с 0-го */ cin>>size; first.SetSize(size); second.SetSize(size); /* вводим основную матрицу */ for(int x =0; x<=size; x++){ for( int y=0; y<=size;y++){ cout<<"\r\nInsert ["<<x<<";"<<y<<"] element of first matrix:"; cin>>element; first.SetValue(element,x,y); } } /* вводим матрицу-столбец с числами*/ for(int x=0; x<=size; x++){ cout<<"\r\nInsert "<<x<<" element of second matrix:"; cin>>element; second.SetValue(element,x,0); } maindet = first.GetDet(); //вычисляем основной определитель(на него будем делить) if(maindet!=0){ for(int x=0;x<=size;x++){ //кол-во элементов(переменных в линейном уравнении) == размерности главной матрицы. //Заменяем колонку, вычисляем определитель , делим на главный определитель, пробуем сократить и выводим temp = first; temp.SetColumn(x,second); //заменянем колонку cout<<"\r\nElement "<<x<<" = "<<temp.GetDet()<<"/"<<maindet; // выводим на экран } }else{ //облом, главный определитель == 0, Крамер не прокатит :((( cout<<"\r\nSorry, but the main determinat of first matrix is 0.Stop."; } // The End cout<<"\r\n\r\nFinish!"; cout<<"\r\nDo you want to again calculate new matrix(1/0)?:"; cin>>c; } return 0; } Ссылка на откомпиленную прогу в первом посте.
Блин я фигею дамы и господа. Вроде же была такая тема - там писали, что нельзя использовать рекурсию. Тут же приходиться вычислять n+1 определитель размером NxN. НИКТО не считает методом крамера, тем более рекурсивно.
Кроме бедных студентов\продвинутых школьников на лабораторных... Чуток подправил парсинг нулевых строк\нулевых элементов на главной диагонале. Теперь всегда корректно работать будет. http://slil.ru/25077981
Так объясните мне - если у нас есть метод гаусса - куда более эффективный и там не надо использовать рекурсию... Мот я чего не понимаю - это новая тенденция писать програму, которая жрет память и которую надо оптимизировать, вместо того, чтобы испольовать простейший алгоритм? попробуй вести у себя в алгоритме первую строку чтонить вроде одной десятитысячной, а остальные элементы - хотя бы вторая строка тысяч 35. а стальные эллементы дробные числа - и посмотри - точно ли у ьебя получаеться решение. Пы сы возьми матрицу хотя бы 250*250.
На практике, метод Крамера использовать действительно не имеет смысла, но дело в том, что его дают написать на лабораторных. И на самом деле, с Крамером ещё хуже, чем кажеться: если понимать под 1 интерацией вычисление определителя матрицы 2х2, умножение его на число и складывание с чем-нибудь, то для вычисления определителя матрицы NxN нужно !N/2 таких интераций. Т.е. 17х17 - ~8кк таких интераций.
прости - ты читал мое предпоследнее сообщение? И кстати раз уж ты так любишь считать - посчитай, сколько у тебя памяти уходит на рекурсию. - сколько ты лишних элементов хранишь. Я тут пониже создал тему - численные методы. /thread53080.html тут только начало - но почитай - будет полезно.