Реализация алгоритма Гаусса-Жордана на С++

      Комментарии к записи Реализация алгоритма Гаусса-Жордана на С++ отключены

В этой теме 0 ответов, 1 участник, последнее обновление  Васильев Владимир Сергеевич 9 мес. назад.

  • Автор
    Сообщения
  • #3083

    При реализации алгоритма Гаусса-Жордана решения систем линейных алгебраических уравнений на С++ удобно хранить расширенную матрицу системы в виде векторов. Проект разделен на несколько файлов (см. раздельная компиляция на С++).
    В main.cpp создается и случайным образом (для примера) заполняется матрица системы, вызывается функция solve (размещенная в модуле method), решающая систему и замеряется время работы этой функции:

    #include <cstdlib>
    #include<iostream>
    #include<vector>
    #include"method.h"
    
    using namespace std;
    
    int main(int argc, char** argv) {
    
      int m,n;
      m = 1500; n = 1501;
      std::vector<std::vector<float> > a(m);
      for (int i=0; i<m; i++){
        for (int j =0;j<n; j++){
          a[i].push_back(  rand() % 100);
        }
      }
      time_t start; 
      time(&start);
      try {
        solve(a);
      }
      catch(char const *err){
        cout<<err<<endl;
        return 1;
      }
      time_t end; 
      time(&end);
      cout<<"Время выполнения: "<<float(end-start)<<endl;    
    
      return 0;
    }

    В файле method.h объявлены функции, необходимые для реализации алгоритма и демонстрации результатов работы. Это функции печати массива, решения СЛАУ, умножения строки матрицы на константу и прибавления к одной строке матрицы элементов другой строки:

    #ifndef METHOD_H
    #define METHOD_H    
    
    void printArr(std::vector<std::vector<float> > &a);
        
    void solve(std::vector<std::vector<float> > &a);
        
    void composition(std::vector<float> &i, std::vector<float> &j, float k);
        
    void divStr(std::vector<float> &d, float k);
    
    #endif

    В файле method.cpp расположены реализации этих функций:

    #include "method.h"
    
    void printArr(std::vector<std::vector<float> > &a){
      for (int i = 0; i<a.size(); i++){
        for (int j = 0; j<a[i].size(); j++){
          std::cout<<a[i][j]<<" ";    
        }
        std::cout<<"\n";
      }
    }
    
    void composition(std::vector<float> &i, std::vector<float> &j, float k){ //  i = j *k +i
      if (i.size() != j.size()){
        throw "Ошибка! Несоответсивие размеров двух векторов!";
      }
      for (int d = 0; d<i.size(); d++){
        i[d] = i[d] + j[d]*k;         
      }
    }
    
    void divStr(std::vector<float> &d, float k){
      if (abs(k) < 0.00000001){
        throw "Ошибка! На 0 делить нельзя!";
      }
      
      for (int i = 0; i<d.size(); i++){
        d[i] = d[i]/k;
      }
    }
    
    void  solve(std::vector<std::vector<float> > &a){     
      for (int k = 0; k<a.size(); k++){
        if (abs(a[k][k]) < 0.00000001){
          for (int i = k+1; i<a.size(); i++){
            if (a[i][k] > 0.00000001){
              std::swap(a[i], a[k]);
              break;
            }
          }
        }
      
        if (a[k][k] < 0.999999999 || a[k][k] > 1.000000001){ 
          divStr(a[k], a[k][k]);
        }
      
        for (int i= k+1; i<a.size(); i++){
          composition(a[i], a[k], -a[i][k]); 
        }
      }
      
      std::cout<<std::endl;
      
      for (int k = a.size()-1; k>=0; k--){
        for (int i = k-1; i>=0; i--){
          composition(a[i], a[k], -a[i][k]);
        }
      }
    }

Для ответа в этой теме необходимо авторизоваться.