【问题标题】:Determinant of a matrix by Gaussian elimination C++通过高斯消元 C++ 确定矩阵的行列式
【发布时间】:2014-09-03 16:07:41
【问题描述】:

我试图找到找到方阵行列式的代码,我遇到了这个代码。

    int det(vector<vector<int> > mat) {
        int n = mat.size();


        for(int col = 0; col < n; ++col) {
            bool found = false;
            for(int row = col; row < n; ++row) {
                if(mat[row][col]) {
                    mat[row].swap(mat[col]);
                    found = true;
                    break;
                }
            }
            if(!found) {
                return 0;
            }
            for(int row = col + 1; row < n; ++row) {
                while(true) {
                    int del = mat[row][col] / mat[col][col];
                    for (int j = col; j < n; ++j) {
                        mat[row][j] -= del * mat[col][j];
                    }
                    if (mat[row][col] == 0)
                        break;
                    else
                        mat[row].swap(mat[col]);
                }
            }
        }

        li res = 1;

        for(int i = 0; i < n; ++i) {
            res *= mat[i][i];
        }
        return abs(res);
    }

但我无法理解第 20-29 行,即从另一行的倍数中减去行的位置。我的意思是为什么这里需要while循环?如我一般 减去商*股息,它应该总是 0 ,对吧?所以我认为它应该只是一次迭代。那么,为什么我们需要执行这个mat[row].swap(mat[col]); 操作呢? 提前致谢。

【问题讨论】:

    标签: c++ matrix gaussian determinants


    【解决方案1】:

    您的代码中有一些奇怪的逻辑来解释您使用整数算术执行计算的事实。

    假设您有一个 3x3 矩阵,其中前两行是:

    4 6 5
    1 2 3
    

    当您为col=0row=1 计算del 时,您将得到:

    del = 1/4 = 0
    

    这样,当你计算时:

    mat[row][j] -= del * mat[col][j];
    

    mat[row][j] 完全没有变化。

    为了解决这个问题,您交换了行。现在前两行是:

    1 2 3
    4 6 5
    

    这样交换行后,del 的值是4/1 = 4。现在一行:

    mat[row][j] -= del * mat[col][j];
    

    确实有所作为。 mat[1][0] 的值最终为零,这正是您所需要的。所以你打破了while 循环。

    这是您的函数的检测版本,它会产生大量调试输出,其中包含用于打印矩阵的辅助函数和用于测试代码的主函数。

    #include <iostream>
    #include <vector>
    #include <stdlib.h>
    
    using namespace std;
    
    void printMatrix(vector<vector<int> > const& mat)
    {
       int n = mat.size();
       for(int row = 0; row < n; ++row) {
          for(int col = 0; col < n; ++col) {
             cout << mat[row][col] << " ";
          }
          cout << "\n";
       }
       cout << "\n";
    }
    
    int det(vector<vector<int> > mat) {
       int n = mat.size();
    
       for(int col = 0; col < n; ++col) {
          cout << "Column: " << col << "\n";
          printMatrix(mat);
          bool found = false;
          for(int row = col; row < n; ++row) {
             if(mat[row][col]) {
                cout << "Got non-zero value for row " << row << " and col " << col << "\n";
                if ( row != col )
                {
                   cout << "(1) Swapping rows " << col << " and " << row << "\n";
                   mat[row].swap(mat[col]);
                   printMatrix(mat);
                }
                else
                {
                   cout << "Not swapping rows\n";
                }
                found = true;
                break;
             }
          }
    
          if(!found) {
             cout << "Did not find a non-zero row. Column: " << col << "\n";
             return 0;
          }
    
          for(int row = col + 1; row < n; ++row) {
             while(true) {
                int del = mat[row][col] / mat[col][col];
                cout << "del: " << del << "\n";
                for (int j = col; j < n; ++j) {
                   mat[row][j] -= del * mat[col][j];
                }
                if (mat[row][col] == 0)
                {
                   break;
                }
                else
                {
                   cout << "(2) Swapping rows " << col << " and " << row << "\n";
                   mat[row].swap(mat[col]);
                   printMatrix(mat);
                }
             }
          }
       }
    
       printMatrix(mat);
       long res = 1;
    
       for(int i = 0; i < n; ++i) {
          res *= mat[i][i];
       }
       return abs(res);
    }
    
    int main()
    {
       vector<vector<int> > mat = { {4, 6, 5}, {1, 2, 3}, {8, 10, 9} };
       int r = det(mat);
       cout << "Determinant: " << r << endl;
       return 0;
    }
    

    【讨论】:

    • 哇!!这是避免矩阵的所有条目都只是整数的浮点精度错误的一种很好的方法。谢谢@R sahu
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-06
    相关资源
    最近更新 更多