【问题标题】:Matrix determinant algorithm C++矩阵行列式算法 C++
【发布时间】:2014-02-08 19:49:38
【问题描述】:

我是编程新手,我一直在寻找一种方法来找到矩阵的行列式。我在网上找到了这段代码,但我无法理解这里的算法。我对 recursion 的基础没有任何问题,但是 continue 和 main 循环我很难理解。非常感谢任何可以向我解释算法的人。

int determ(int a[MAX][MAX],int n) {
  int det=0, p, h, k, i, j, temp[MAX][MAX];
  if(n==1) {
    return a[0][0];
  } else if(n==2) {
    det=(a[0][0]*a[1][1]-a[0][1]*a[1][0]);
    return det;
  } else {
    for(p=0;p<n;p++) {
      h = 0;
      k = 0;
      for(i=1;i<n;i++) {
        for( j=0;j<n;j++) {
          if(j==p) {
            continue;
          }
          temp[h][k] = a[i][j];
          k++;
          if(k==n-1) {
            h++;
            k = 0;
          }
        }
      }
      det=det+a[0][p]*pow(-1,p)*determ(temp,n-1);
    }
    return det;
  }
}

【问题讨论】:

  • 计算未成年人的行列式。内部循环在temp 中形成未成年人。此外,这是一种计算行列式的可怕方法。
  • @user3144334 次要矩阵是一排一列的矩阵。这里使用的未成年人都是第一行被扔掉的,要扔pth列,你必须在将元素从a复制到temp时跳过它
  • 以超指数的复杂性计算行列式,干得好……甚至是pow(-1,p),一眼就能看出代码有多好……

标签: c++ algorithm matrix determinants


【解决方案1】:
#include <iostream>

using std::cin;
using std::cout;
using std::endl;

int **submatrix(int **matrix, unsigned int n, unsigned int x, unsigned int y) {
    int **submatrix = new int *[n - 1];
    int subi = 0;
    for (int i = 0; i < n; i++) {
        submatrix[subi] = new int[n - 1];
        int subj = 0;
        if (i == y) {
            continue;
        }
        for (int j = 0; j < n; j++) {
            if (j == x) {
                continue;
            }
            submatrix[subi][subj] = matrix[i][j];
            subj++;
        }
        subi++;
    }
    return submatrix;
}

int determinant(int **matrix, unsigned int n) {
    int det = 0;
    if (n == 2) {
        return matrix[0][0] * matrix[1][1] - matrix[1][0] * matrix[0][1];
    }
    for (int x = 0; x < n; ++x) {
        det += ((x % 2 == 0 ? 1 : -1) * matrix[0][x] * determinant(submatrix(matrix, n, x, 0), n - 1));
    }

    return det;
}

int main() {
    int n;
    cin >> n;
    int **matrix = new int *[n];
    for (int i = 0; i < n; ++i) {
        matrix[i] = new int[n];
        for (int j = 0; j < n; ++j) {
            cin >> matrix[i][j];
        }
    }

    cout << determinant(matrix, n);

    return 0;
}

【讨论】:

    【解决方案2】:

    该算法使用分治法来解决问题(找到 N*N 矩阵的行列式)。

    该算法使用递归模式,这是一种分而治之的方法。您可以通过注意算法在第三个条件语句中调用自身来发现这一点。

    每个递归算法都有一个退出条件,它是代码中的第一个 if 语句。它们还包含一个部分,该部分是最方便的问题的解决方案,或者是最初难以解决的主要大问题的原子问题。原子问题或最分裂的问题可以很容易地解决,因为您可以看到代码的第二个 if 语句。在您的情况下,它实际上是在解决 2*2 矩阵的行列式。

    你的代码中最重要的部分是你进行除法的部分(这也是递归的!)。 这部分是征服的关键。通过一些回溯和数值示例,您可以找到它:

    det = det + a[0][p] * pow(-1,p) * determ(temp,n-1);
    

    对于最后的建议,尝试一个 3*3 矩阵,它只需要一个除法。 祝你好运。

    This book is a great one to start studying and understanding algorithms

    【讨论】:

    • 非常感谢 我只想问 continue 语句是做什么的?如果 j == p 那么你直接跳到 det=det+a[0][p]*pow(-1,p)*determ(temp,n-1);还是别的什么?
    • @user3144334 哦,你只是不知道continue 做了什么...for (...) { if (x) { continue; } b; c; } 相当于for (...) { if (!x) { b; c; } }
    • 它继续'for'循环再执行一次。检查一下:cplusplus.com/doc/tutorial/control - continue 可用于所有具有条件的语句:tutorialspoint.com/cplusplus/cpp_continue_statement.htm
    猜你喜欢
    • 2019-03-25
    • 2013-05-12
    • 2011-02-24
    • 2015-01-16
    • 1970-01-01
    • 1970-01-01
    • 2018-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多