置换矩阵

时间:2011-11-05 13:05:06

标签: algorithm data-structures

是否可以将matrix An列和n列分解为m [n x n]置换矩阵的总和。其中m是matrix A中每行和每列的1的数量?

更新

是的,这是可能的。我遇到了这样一个例子,如下所示 - 但我们怎样才能概括出答案呢?

enter image description here

3 个答案:

答案 0 :(得分:0)

对于第一个排列矩阵,取第一行中的第一个。对于第二行,请获取您尚未拥有的列中的第一行。对于第三行,请获取您尚未拥有的列中的第一行。等等。对所有行执行此操作。

您现在有一个排列矩阵。

接下来从原始矩阵中减去第一个置换矩阵。现在,这个新矩阵在每行和每列中都有m-1个。因此,请多次重复此过程m-1,然后您将拥有m个排列矩阵。

您可以跳过最后一步,因为每行和每列中一个1的矩阵已经是一个置换矩阵。没有必要进行任何计算。

这是一种贪婪的算法并不总是有效。我们可以通过稍微改变选择规则来使其工作。见下文:

对于你的例子:

    1 0 1 1
A = 1 1 0 1
    1 1 1 0
    0 1 1 1

在第一步中,我们为第一行选择(1,1),为第二行选择(2,2),为第三行选择(3,3),为第四行选择(4,4)。然后我们有:

    1 0 0 0   0 0 1 1
A = 0 1 0 0 + 1 0 0 1
    0 0 1 0   1 1 0 0
    0 0 0 1   0 1 1 0

第一个矩阵是置换矩阵。第二个矩阵在每行和每列中恰好有两个1。所以我们按顺序选择:(1,3),(2,1),(3,2)和...我们遇到了麻烦:第4列中包含1的行已经被使用过。

那么我们该如何解决这个问题呢?好吧,我们可以跟踪每列中剩余1的数量。我们选择剩余1的最小数量的列,而不是选择未使用的第一列。对于上面的第二个矩阵:

    0 0 1 1     0 0 X 0     0 0 X 0     0 0 X 0
B = 1 0 0 1 --> 1 0 0 1 --> 0 0 0 X --> 0 0 0 X
    1 1 0 0     1 1 0 0     1 1 0 0     X 0 0 0
    0 1 1 0     0 1 1 0     0 1 1 0     0 1 1 0
    -------     -------     -------     -------
    2 2 2 2     2 2 X 1     1 2 X X     X 1 X X

因此,我们将在第二步中选择第4列,在第3步中选择第1列,在第4步中选择第2列。

始终只能有一列,其中一列剩余1.另一列必须已在前m-1行中删除。如果你有两个这样的列,其中一个必须被选为之前的最小列。

答案 1 :(得分:0)

您想要的是1-factorization。一种算法反复找到完美匹配并将其删除;可能还有其他人。

答案 2 :(得分:0)

这可以使用递归(回溯或深度优先遍历)算法轻松完成。以下是其解决方案的伪代码

void printPermutationMatrices(const int OrigMat[][], int permutMat[], int curRow, const int n){
//curPermutMatrix is 1-D array where value of ith element contains the value of column where 1 is placed in ith row
    if(curRow == n){//Base case
        //do stuff with permutMat[]
        printPermutMat(permutMat);
        return;
    }

    for(int col=0; col<n; col++){//try to place 1 in cur_row in each col if possible and go further to next row in recursion
        if(origM[cur_row][col] == 1){
            permutMat[cur_row] = col;//choose this col for cur_row
            if there is no conflict to place a 1 in [cur_row, col] in permutMat[]
                perform(origM, curPermutMat, curRow+1, n);
    }

    }
}

以下是如何从您的主要功能调用:

int[] permutMat = new int[n];
printPermutationMatrices(originalMatrix, permutMat, 0, n);