Algorithm 动态规划问题,在0-1矩阵中选择1,使每行和每列正好包含一个1

Algorithm 动态规划问题,在0-1矩阵中选择1,使每行和每列正好包含一个1,algorithm,matrix,dynamic-programming,Algorithm,Matrix,Dynamic Programming,给定一个0-1的平方矩阵,我们可以通过多少种方式选择1,使每行和每列正好包含一个1 我已经为这个问题实现了以下回溯代码: int countways(int A[][], int& n, int row, vector<bool> columnselected ) { if(row == n) return 1; int result = 0; for( j = 0; j < n

给定一个0-1的平方矩阵,我们可以通过多少种方式选择1,使每行和每列正好包含一个1

我已经为这个问题实现了以下回溯代码:

    int countways(int A[][], int& n, int row, vector<bool> columnselected ) {
         if(row == n)
              return 1;
         int result = 0;
         for( j = 0; j < n ; ++j) {
              if(A[row][j]) {
                   if(!columnselected[j]) {
                        columnselected[j] = true;
                        result+ = countways(A, n, row+1, columnselected);
                        columnselected[j] = false;
                   }
               }
         }
         return result;
     }
int countways(选择int A[][],int&n,int行,向量列){
如果(行==n)
返回1;
int结果=0;
对于(j=0;j
这绝对不是解决这个问题的最好办法。我不能通过使用递归的记忆版本来增强解决方案,因为对递归的每次调用中的columnselected和row对于每个子问题都是唯一的


请建议一种更好的方法来解决这个问题,更像是一种动态规划解决方案,比这个显而易见的解决方案更有效。

恐怕你最好的选择是修改Knuth的算法X,详细解释见。关键是使用与算法X类似的数据结构


我很确定你描述的问题相当于精确覆盖,这使得它是NP完全的。因此,没有“有效”的解决方案可用,但算法X在实践中是可以接受的。

如果我正确理解您的问题,这个问题不就是给每个列授予唯一的等级吗?例如,如果[p,q]上有一个1,这意味着第q列被分配了一个秩p

所以对于NxN矩阵,解应该是N!(N的阶乘)

您还可以使用归纳法p(N)=N*p(N-1),因为当您在NxN矩阵中的任意位置放置一个1时,一行和一列都会被它阻止-因此您只剩下一个(N-1)x(N-1)矩阵

编辑:我对问题的理解不正确。但这里有一个新的尝试,即使用动态规划方法


让我们先创建一个DAG,如下所示: 此图的节点是正方形(p,q,size)-固定在row=p,col=q处的正方形,带有大小x大小元素。是的,他们可以绕着。 为了计算简单,让q始终等于0

对于矩阵{abc}、{def}、{ghi},节点将是

{a} ,{d},{g}:大小为1的正方形:根节点

{ab,de},{de,gh},{gh,ab}:大小为2的正方形

{{abc},{def},{ghi}}:大小为N的唯一平方,即矩阵本身:叶节点

有向边指向大小为n到n+1的正方形,如果小正方形可以包含在大正方形中。 例如{d}同时指向{ab,de}和{de,gh} 重要提示:尺寸n和尺寸n+2正方形之间不能有任何边

遍历

基础:为大小为1的正方形指定权重:正方形(p,0,1)=1 iff M(p,0)==1

步骤:对于大小为N的正方形,请访问其儿童,即大小为N+1的正方形。如果孩子的体重增长到1,则为其贡献自己的体重,否则不要

叶节点将有您的答案


此解决方案基本上是一种自下而上的遍历方法,它将避免子问题的重复计算。

此问题相当于查找子问题的数量。取NxN矩阵,为每行创建一个顶点,为每列创建一个顶点(2N个顶点)。如果矩阵在相应的行和列中包含“1”,则在行顶点和列顶点之间添加边。这形成了二部图。请注意,在该图中找到完美匹配相当于选择“1”,以便每行和每列正好包含一个1”

发件人:

确定给定区域中完全匹配数的问题 图为#P完整图(见永久图)。然而,一个值得注意的定理 Kasteleyn指出平面图中完美匹配的数量 图可以通过FKT在多项式时间内精确计算 算法。同样,对于二部图,问题可以是 在多项式时间内近似求解。[]即,对于任何ε>0, 有一种概率多项式时间算法可以确定, 在高概率情况下,一个区域内的完全匹配数M 误差不超过εM

注意:您可以在多项式时间内确定答案是否为零



因此,一个完美的多项式时间解是不可能的,但是我们可以通过使用改进函数的渐近运行时间(从O(N*N!)到O(N*2^N))。只有“columnselected”变量需要“memo”(将“columnselected”更改为位掩码整数而不是向量也可以提高性能并具有更简单的实现)。

我们以这种情况为例,给定0-1矩阵M=[[0,1,1],[1,0],[0,1,0],[0,1,0]],您可以看到选择1的方法只有一种,即,从M[0][2]、M[1][0]和M[2][1],没有3=此矩阵的6种方法。问题不是在矩阵中安排n1,这是一个给定的矩阵,我们只能从这个矩阵中选择1s。@belisarius现在我看到这是可以做到的,但我担心这仍然不是多项式时间,计算Rook多项式需要计算匹配多项式,这是一个#P-完全问题。我们能在多项式时间内完成这件事吗?哦,我明白了,我的错。我删除了以前的评论,因为它们具有误导性。