从逻辑矩阵中获取最大置换矩阵

时间:2015-02-15 02:06:28

标签: math matrix permutation logical-operators

A (m行,n列)是(0,1)-Matrix(或逻辑矩阵)。

如何从 A 获得子矩阵 B (p行,p列),满足 B 是一个置换矩阵和p是最大的?例如,

enter image description here

PS:permutation matrix是一个方形二进制矩阵,每行中只有一个条目1,每列只有0和0。

1 个答案:

答案 0 :(得分:1)

一种可能性是利用每个排列矩阵可以一次构建一行和一列。 所以我们可以采用一定大小的每个排列矩阵,尝试用所有可能的行或列扩展它, 并查看一个更大的排列矩阵的结​​果。

运行时间不是那么好。我认为它类似于O(2^(m+n))。 (我使用过Python,FWIW。)

#!/usr/local/bin/python3

import itertools

A = ((0,1,0,0),
     (0,0,1,0),
     (0,1,1,0),
     (1,0,0,1))
maximalSubmatrices = { ( (), () ), }
# each tuple is a tuple of rows and then columns
maxP = 0

def isPerm(rows,cols):
    if ( len(rows) != len(cols) ):
        return False
    for row in rows:
        if not exactlyOne( A[row][col] for col in cols ):
            return False
    for col in cols:
        if not exactlyOne( A[row][col] for row in rows ):
            return False
    return True

def exactlyOne(sequence):
    return sum( 1 for elt in sequence if elt ) == 1

while True:
    moreMaxl = set()
    for submatrix in maximalSubmatrices:
        for row,col in itertools.product(range(len(A)),range(len(A[0]))):
            if ( row not in submatrix[0] and col not in submatrix[1] ):
                moreMaxl.add( ( tuple(sorted(submatrix[0]+(row,))) , tuple(sorted(submatrix[1]+(col,))) ) )
    moreMaxl = set( ( maxl for maxl in moreMaxl if isPerm(*maxl) ) )
    if ( len(moreMaxl) ):
        maxP += 1
        maximalSubmatrices = moreMaxl
    else:
        break

for maxl in maximalSubmatrices:
    print("maximal rows: ",maxl[0],"\nmaximal cols: ",maxl[1],end="\n\n")
print("maximum permutation size is: ",maxP)

输出结果为:

maximal rows:  (0, 1, 3) 
maximal cols:  (0, 1, 2)

maximal rows:  (0, 1, 3) 
maximal cols:  (1, 2, 3)

maximum permutation size is:  3

<强>解释

在Python中,tuple是一个不可变的对象数组。因为它是不可变的,所以它可以被散列并成为集合的元素。所以maximalSubmatrices是制作子矩阵所需的一组行和列。在Java中,我们会做类似的事情:

class Submatrix {
    List<Integer> rows;
    List<Integer> columns;
    public int hashCode();
    public boolean equals(Object);
}
Set<Submatrix> maximalSubmatrices;

但是Python可以自己处理所有这些。

我们从制作大小为0的子矩阵所需的行和列开始:两者都是空元组()。每次通过while循环,我们采用所有可能的行,列对,并查看该行,列是否可以扩展当前的排列矩阵(换句话说,它们不在矩阵中)。如果是,我们将扩展矩阵添加到集合moreMaxl。然后我们通过moreMaxl并仅保留排列矩阵。如果moreMaxl中仍有元素,那么它们的排列矩阵比maximalSubmatrices中的矩阵大一个。由于我们可以扩展,while循环继续。

相关问题