簡體   English   中英

遵循Glynn公式計算永久性的矩陣相乘問題

[英]Problem with multiplication of matrices following Glynn's formula for calculating the permanent

我正在嘗試使用Glynn公式在C ++中實現矩陣永久性的計算

在此處輸入圖片說明

我嘗試簡要解釋一下此公式的工作原理。 假設我們有一個nxn矩陣。

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

要使用Glynn公式計算永久值,我應該嘗試執行矩陣的“一種”乘積,其中矩陣是長度為2^n的真值表,具有n/2行和n列。

這樣的事情。 假設一個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- = -1 )。 所以我要做的產品是:

| 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的第一列乘以符號矩陣的第一行(右)。符號矩陣的第二行(錯誤!我也應該將第二列乘以符號矩陣的第一行,如書面公式所示)。

有什么建議么?

我認為您確實需要仔細檢查您對方程式的理解。 請記住,每個求和或乘法都是for循環。 因此,通過使用原始論文中的符號,您將獲得:

#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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM