[英]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, b
和c
的正號。
順序是:將矩陣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.