A (m行,n列)是(0,1)-Matrix(或逻辑矩阵)。
如何从 A 获得子矩阵 B (p行,p列),满足 B 是一个置换矩阵和p是最大的?例如,
PS:permutation matrix是一个方形二进制矩阵,每行中只有一个条目1,每列只有0和0。
答案 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循环继续。