在矩阵中找到最大相同行方形的算法

时间:2015-03-20 15:56:22

标签: algorithm math matrix graph-algorithm

我有一个100x100大小的矩阵,需要找到最大的行和列集合,这些行和列创建一个具有相等行的正方形。例如:

  A B C D E F               C D E 
a 0 1 2 3 4 5         a     2 3 4 
b 2 9 7 9 8 2                       
c 9 0 6 8 9 7   ==>                   
d 8 9 2 3 4 8         d     2 3 4    
e 7 2 2 3 4 5         e     2 3 4
f 0 3 6 8 7 2          

目前我正在使用此算法:

candidates = [] // element type is {rows, cols}
foreach row
    foreach col
        candidates[] = {[row], [col]}
do
    retval = candidates.first
    foreach candidates as candidate
        foreach newRow > candidates.rows.max
            foreach newCol > candidates.cols.max
                // compare matrix cells in candidate to newRow and newCol
                if (newCandidateHasEqualRows)
                    newCandidates[] = {candidate.rows+newRow, candidate.cols+newCol}
    candidates = newCandidates
while candidates.count
return retval

还有其他人遇到类似的问题吗?是否有更好的算法来解决它?

2 个答案:

答案 0 :(得分:4)

这是我提到的NP-硬度降低,来自biclique。给定二分图,为部分A中的每个顶点创建一个行,并为部分B中的每个顶点创建一个列。对于每个存在的边,在相应的矩阵条目中放置一个0。为每个其他矩阵条目添加唯一的正整数。对于所有s> 1,当且仅当存在大小为s的平方(必须全部为零)时,才有一个K s,s 子图。

给定一组固定的行,可以轻松确定最佳的列集。您可以在行集上尝试a priori algorithm,其中一组行被视为频繁如果存在尽可能多的列,则这些行与行一起形成有效的正方形。

答案 1 :(得分:1)

我已在branch and bound的C ++中针对此问题实施了http://pastebin.com/J1ipWs5b解算器。令我惊讶的是,它实际上可以很快地解决大小高达100x100的随机生成的谜题:在从0-9随机选择的每个矩阵单元的一个问题上,在我的旧笔记本电脑上发现了大约750ms的最佳4x4解决方案。随着单元格条目的范围缩小到0-1,解决方案时间变得非常长 - 但仍然是157s(对于我尝试的一个问题,它有8x8最优解决方案),这不是可怕。它似乎对最优解的大小非常敏感。

在任何时候,我们都有一个部分解决方案,其中包含一组明确包含的行,以及一组明确排除的行。 (其余行的包含状态尚未确定。)首先,我们选择剩下的行到#34;尝试"。我们尝试包括行;然后(如果需要;见下文)我们尝试排除它。 "尝试"这意味着递归地解决相应的子问题。我们记录在解决方案中明确包含的所有行中相同的列集。当行添加到部分解决方案时,这组列只能缩小。

当我们确定我们无法将当前的部分解决方案发展为比我们拥有的一些完整解决方案更好(即更大)的完整解决方案时,除了标准B& B关于修剪搜索的想法之外还有一些改进已找到:

  1. 支配规则。如果有任何行可以添加到当前的部分解决方案而根本不收缩相同列的集合,那么我们可以安全地立即添加它们,我们永远不必考虑添加它们。这可能会节省大量分支,特别是如果输入中有许多类似的行。
  2. 我们可以任意重新排序剩余的(不是明确包含或明确排除的)行。所以特别是,我们总是可以选择下一行来考虑 most 收缩相同列的行:这个(也许是违反直觉的)策略可以消除附近的行的坏组合。搜索树的顶部,可以加快搜索速度。它也恰好补充了上面的优势规则,因为它意味着如果有两行X和Y使得X保留Y保留的相同列的严格子集,那么X将首先添加到解决方案中,其中转向意味着每当包含X时,Y将被强制规则强制进入,我们不需要考虑包含X但排除Y的可能性。