Метод Гаусса[c++]

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Ky3bMu4, 2 Nov 2007.

  1. Ky3bMu4

    Ky3bMu4 Elder - Старейшина

    Joined:
    3 Feb 2007
    Messages:
    487
    Likes Received:
    284
    Reputations:
    42
    Методы Гаусса и Крамера[c++]

    Как-то на кряклабе нашёл несколько примеров по решению систем линейных уравнений этим методом. Но 404. :( . Решил написать сам.
    Для привидения матрицы к главному ступенчатому виду использовал метод ведущего элемента(для машины он проще чем сначала получение верхне треугольной матрицы , а потом самого вида.)
    Т.к. часто попадаются "плохие" числа и приходится работать с дробями, то написал класс для дробей, перегрузил операторы *, / , + , - . Сделал функции 1, 2 и 3 элементарных преобразований.
    Также есть алгоритм оброботки нулевых эллемтов на главной диагонале.Для этого написал отдельно класс для матриц.
    Ввод матрицы осуществляется в самой программе. Программа таже показывает пошагово значения матриц.

    Приводить весь алгоритм небуду, т.к. он очень большой. Исходники и откомпиленная прога ниже(вместе с Крамером):

    http://slil.ru/25072002
    http://ifolder.ru/4038710
    http://rapidshare.com/files/68056699/Gauss_Kramer.rar.html
     
    #1 Ky3bMu4, 2 Nov 2007
    Last edited: 7 Nov 2007
    2 people like this.
  2. Ni0x

    Ni0x Elder - Старейшина

    Joined:
    27 Aug 2006
    Messages:
    338
    Likes Received:
    157
    Reputations:
    37
    Ты бы лучше за свой ужасный С++ извинился. Что уж говорить, если ты не знаешь как через cout переменную вывести. Использовать код вида:
    Code:
    printf("Insert %d element of second matrix:",x);
    cin>>temp;
    cout<<"\r\n";
    
    это норм по твоему? Но больше всего конечно порадовало подключение windows.h ради функции ExitProcess. Ты только не подумай, что я опять наезжаю на тебя или еще чего.
     
    2 people like this.
  3. KEZ

    KEZ Ненасытный школьник

    Joined:
    18 May 2005
    Messages:
    1,604
    Likes Received:
    754
    Reputations:
    397
    Ni0x, ты че, это кроссплатформеный Опен-Сурс от Кузьмича.
    А вот это вообще будет висеть у меня на стенке в корридоре

    Ещё. Крутой деструктор
    )))))

    Ну и самый прикол
    на всякий случай кодер решил везде написать (по всему тексту прямо) "drob::" чтоб вдруг что....гыгы
     
  4. Constantine

    Constantine Elder - Старейшина

    Joined:
    24 Nov 2006
    Messages:
    798
    Likes Received:
    710
    Reputations:
    301
    Я лучше столбиком буду делить...
     
  5. alextoun

    alextoun Вылет с Трассы

    Joined:
    7 May 2006
    Messages:
    563
    Likes Received:
    216
    Reputations:
    96
    не удивительно, шо у меня ошибки при компеляци))
    кстате я метод гаус на 5 сдал!!! имея 3 по математике в школе по жизни :)
     
  6. .Slip

    .Slip Elder - Старейшина

    Joined:
    16 Jan 2006
    Messages:
    1,571
    Likes Received:
    976
    Reputations:
    783
    Идея норм, сурс ужасен=\
     
  7. Ky3bMu4

    Ky3bMu4 Elder - Старейшина

    Joined:
    3 Feb 2007
    Messages:
    487
    Likes Received:
    284
    Reputations:
    42
    Ну и какие-же это ошибки?

    Так:
    Code:
    printf("Insert %d element of second matrix:",x);
    
    Намного удобнее и короче, чем:
    Code:
    cout<<"Insert  "<<x<< " element of second matrix:";
    
    Неправдали?
     
  8. Ky3bMu4

    Ky3bMu4 Elder - Старейшина

    Joined:
    3 Feb 2007
    Messages:
    487
    Likes Received:
    284
    Reputations:
    42
    Большое спасибо за критику. Учёл.
    Улучшил Гаусса, добавил обработку нулевых элементов на главной диагонале.

    Вот, ещё написал метод Крамера с рекурсивным вычислением определителя.
    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;
    }
    
    
    

    Ссылка на откомпиленную прогу в первом посте.
     
    3 people like this.
  9. ak[id]

    ak[id] Elder - Старейшина

    Joined:
    22 Jun 2007
    Messages:
    143
    Likes Received:
    95
    Reputations:
    10
    Спасибо, мы ща в уневере как раз ща решаем матрицы методом Гауса и Крамера.
     
    1 person likes this.
  10. GlOFF

    GlOFF Elder - Старейшина

    Joined:
    8 May 2006
    Messages:
    689
    Likes Received:
    484
    Reputations:
    4
    Да бред все это! Используйте метод Гаусаса.
     
    1 person likes this.
  11. ~Lexx~

    ~Lexx~ Elder - Старейшина

    Joined:
    30 Sep 2006
    Messages:
    195
    Likes Received:
    28
    Reputations:
    0
    Блин я фигею дамы и господа. Вроде же была такая тема - там писали, что нельзя использовать рекурсию. Тут же приходиться вычислять n+1 определитель размером NxN. НИКТО не считает методом крамера, тем более рекурсивно.
     
  12. Ky3bMu4

    Ky3bMu4 Elder - Старейшина

    Joined:
    3 Feb 2007
    Messages:
    487
    Likes Received:
    284
    Reputations:
    42
    Кроме бедных студентов\продвинутых школьников на лабораторных...

    Чуток подправил парсинг нулевых строк\нулевых элементов на главной диагонале. Теперь всегда корректно работать будет.

    http://slil.ru/25077981
     
  13. ~Lexx~

    ~Lexx~ Elder - Старейшина

    Joined:
    30 Sep 2006
    Messages:
    195
    Likes Received:
    28
    Reputations:
    0
    Так объясните мне - если у нас есть метод гаусса - куда более эффективный и там не надо использовать рекурсию... Мот я чего не понимаю - это новая тенденция писать програму, которая жрет память и которую надо оптимизировать, вместо того, чтобы испольовать простейший алгоритм? попробуй вести у себя в алгоритме первую строку чтонить вроде одной десятитысячной, а остальные элементы - хотя бы вторая строка тысяч 35. а стальные эллементы дробные числа - и посмотри - точно ли у ьебя получаеться решение. Пы сы возьми матрицу хотя бы 250*250.
     
  14. Ky3bMu4

    Ky3bMu4 Elder - Старейшина

    Joined:
    3 Feb 2007
    Messages:
    487
    Likes Received:
    284
    Reputations:
    42
    На практике, метод Крамера использовать действительно не имеет смысла, но дело в том, что его дают написать на лабораторных.

    И на самом деле, с Крамером ещё хуже, чем кажеться: если понимать под 1 интерацией вычисление определителя матрицы 2х2, умножение его на число и складывание с чем-нибудь, то для вычисления определителя матрицы NxN нужно !N/2 таких интераций. Т.е. 17х17 - ~8кк таких интераций.
     
  15. ~Lexx~

    ~Lexx~ Elder - Старейшина

    Joined:
    30 Sep 2006
    Messages:
    195
    Likes Received:
    28
    Reputations:
    0
    прости - ты читал мое предпоследнее сообщение? И кстати раз уж ты так любишь считать - посчитай, сколько у тебя памяти уходит на рекурсию. - сколько ты лишних элементов хранишь. Я тут пониже создал тему - численные методы.
    /thread53080.html
    тут только начало - но почитай - будет полезно.