【问题标题】:Problem with multiplication of matrices following Glynn's formula for calculating the permanent遵循 Glynn 计算永久值的公式的矩阵乘法问题
【发布时间】:2019-06-12 17:06:46
【问题描述】:

我正在尝试在 C++ 中实现 Glynn formula 之后的矩阵永久计算。

我试图简要解释一下这个公式是如何工作的。假设我们有一个nxn 矩阵。

| a b c |
| d e f | 
| g h i |

要使用 Glynn 公式计算永久值,我应该尝试用一个矩阵执行“一种”矩阵乘积,该矩阵是一个长度为 2^n 的真值表,行和 n/2n 列。

类似的东西。假设一个矩阵为n = 3

| a b c | |+ + +|
| d e f | |+ - +|
| g h i | |+ + -|
          |+ - -|

公式的开发。我必须得到:

∆(a + b + c)(d + e + f)(g + h + i)

地点:

è 等于第一个符号矩阵的乘积(因此是+ * + * + = +)。 a, bc的正号是用字母矩阵的第一列乘以符号矩阵第一行的符号得到的。

那么顺序是:将矩阵A的第一列与符号矩阵的第一行相乘,将矩阵A的第二列与符号矩阵的第一行相乘,然后将矩阵A的最后一列相乘对于符号矩阵的第一行。

这是第一步。第二种方法是将矩阵 A 的第一列与符号矩阵的第二行相乘,将矩阵 A 的第二列与符号矩阵的第二行相乘,然后将矩阵 A 的第三列与第二行相乘一排矩阵符号等等..

最终结果是这样的:

= + (a + b + c)(d + e + f)(g + h + i) 
  - (a - b + c)(d - e + f)(g - h + i) 
  - (a + b - c)(d + e - f)(g + h - i)
  + (a - b - c)(d - e - f)(g - h - i)

我正在尝试在 C 中实现此算法。我已正确创建了一个随机矩阵 nxn 和我以这种方式对其进行编码的符号矩阵,以便以简单的方式执行乘法(+ = 1 和 @ 987654339@)。 所以我要做的产品是:

| a b c | |1  1  1|
| d e f | |1 -1  1|
| g h i | |1  1 -1|
          |1 -1 -1|

我尝试创建的用于运行这些产品和总和的函数是:

double permanent(double input_matrix[n][n], int sign_matrix[][n]){

int rows =  pow (2, n) ;
int partial_result = 0;
int result = 1;

for(int r = 0; r < n; r++)
{
   for(int c = 0; c < n; c++)
   {
      partial = partial + input_matrix[c][r] * sign_matrix[r][c];
      //cout << parziale <<  endl;
   }

   cout << partial << endl;
   partial_result = partial_result * parziale;
   partial = 0;

}

问题是,当我执行partial = partial + input_matrix [c][r] * sign_matrix [r][c]; 时,我不能“保持符号矩阵的线稳定,导致乘积错误,因为我将矩阵 A 的第一列乘以符号矩阵(右)。符号矩阵的第二行(错误!我还应该将符号矩阵的第一行的第二列乘以书面公式)。

有什么建议吗?

【问题讨论】:

  • 我认为你的矩阵乘积是错误的。它应该是 S*A,其中 S 是符号矩阵
  • 你是对的。我试着改变,看看它是否会到来。

标签: c++ math matrix


【解决方案1】:

我认为您确实需要检查两次您对方程式的理解。请记住,每个求和或乘法都是一个 for 循环。因此,通过使用original paper 中的符号,您可以得到:

#include <vector>
#include <cassert>

using mat = std::vector<std::vector<double>>;

double permanent(const mat& input_matrix, const mat& sign_matrix)
{
    int m = input_matrix.size();
    assert(m > 2);
    assert(input_matrix[0].size() == m);
    assert(sign_matrix.size() == m);
    int cols = sign_matrix[0].size();
    assert(cols == 1 << (m - 1));

    double result = 0;
    for (int t = 0; t < cols; ++t) {
        double delta = 1;
        for (int k = 0; k < m; ++k) {
            delta *= sign_matrix[k][t];
        }
        double p = 1;
        for (int j = 0; j < m; j++) {
            double s = 0;
            for (int i = 0; i < m; i++) {
                s += sign_matrix[i][t] * input_matrix[i][j];
            }
            p *= s;
        }
        result += delta * p;
    }
    return result / cols;
}

int main()
{
    mat A = { 
        { 1, 4, 7, }, 
        { 2, 5, 8, }, 
        { 3, 6, 9, },
    };
    mat sign_mat = {
        { 1,  1,  1,  1, },
        { 1, -1,  1, -1, },
        { 1,  1, -1, -1, },
    };
    auto perA = permanent(A, sign_mat);
}

【讨论】:

    猜你喜欢
    • 2014-08-02
    • 2014-12-07
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多