Algorithm 矩阵的每行和每列中正好有一个值

Algorithm 矩阵的每行和每列中正好有一个值,algorithm,matrix,Algorithm,Matrix,我试图找出解决此问题的最佳方法: 有这样一个矩阵: 1 0 0 1 0 1 1 0 1 0 1 1 0 0 1 0 0 1 1 0 1 0 1 0 0 我们希望找出每一个可能的矩阵,其中每行和每列中只有一个1,例如,该矩阵是一个可能的解决方案: 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 我认为您可以找到一个解决方案,通过循环遍历每个可能的组合,并检查每行和每列中是否正好有一个1?有没有已知的算法? 是否有可能计算出解决方案,而不是尝试


我试图找出解决此问题的最佳方法: 有这样一个矩阵:

1 0 0 1 0
1 1 0 1 0
1 1 0 0 1
0 0 1 1 0
1 0 1 0 0
我们希望找出每一个可能的矩阵,其中每行和每列中只有一个1,例如,该矩阵是一个可能的解决方案:

1 0 0 0 0
0 1 0 0 0
0 0 0 0 1
0 0 0 1 0
0 0 1 0 0
我认为您可以找到一个解决方案,通过循环遍历每个可能的组合,并检查每行和每列中是否正好有一个1?有没有已知的算法? 是否有可能计算出解决方案,而不是尝试所有的可能性

多谢各位

编辑: 一种可能的解决方案(但代价高昂)可能是生成每个理论上可能的矩阵,例如(使用3x3矩阵,因为它较短): 一,

二,

三,

四,

五,

等等

然后,我们可以检查每个生成的矩阵,如果原始矩阵在给定位置有1。如果是,这是一个解决方案


生成所有这些矩阵需要哪些循环?

我已经编写了以下简单代码(使用矩阵):

我希望它对您有用。

编辑: 根据你的评论,我重新阅读了原来的问题,意识到我完全没有抓住问题的关键。我将在这里发布一个(希望)更相关的答案,但是人们可以随意撤销任何投票。我讨论过发布一个新的答案并删除这个答案,如果人们认为这是一条路,我仍然可以这样做

新答案: 以下是我现在如何理解你的问题。给定一个平方二元矩阵a,求出所有矩阵B,使得每行B中的元素和为1,每列中的元素和为1,对于所有元素B(r,c)==1,原始矩阵a(r,c)==1的对应元素

编辑2: 这里的问题是,您希望找到所有的解决方案。而且有很多。对于所有1的nxn矩阵,您将拥有
n解决方案。对于每一行都有
m
1的矩阵,您可能会有如下内容

mn-m*m

解决方案。因此,即使你有一个非确定性的算法在O(1)时间内生成所有的解,简单地打印出来的时间复杂度仍然是指数级的

正如Smith42先生在评论中提到的,您可能需要进行回溯搜索,但您可以做一些事情来减少搜索空间:

您可以进行的最简单检查是在中查找只有一个1的行/列。(显然,如果有任何行/列的no1,则没有有效的解决方案。)如果行r在列c中只有一个1,则将列c中的所有其他元素设置为0。同样,如果列c在行r中只有一个1,则将所有其他元素设置为 行r到0。在您的示例中:

1 0 0 1 0     1 0 0 1 0     1 0 0 1 0
1 1 0 1 0     1 1 0 1 0 ==> 0 1 0 0 0
1 1 0 0 1 ==> 0 0 0 0 1     0 0 0 0 1
0 0 1 1 0     0 0 1 1 0     0 0 1 1 0
1 0 1 0 0     1 0 1 0 0     1 0 1 0 0
第5列中只有一个1,因此B中的第3行必须在B(3,5)处有一个1才能有效。这意味着我们可以修改输入矩阵A,并在不丢失任何有效解的情况下(稍微)减少搜索空间。现在,第2列中只有一个1,可以将第2行中的其他值设置为0

接下来,您可以在搜索过程中使用前向检查,以防止在不可能找到有效解决方案的子矩阵中进行搜索。假设您得到以下矩阵:

1 0 0 1 0
0 1 1 0 1
1 1 0 0 1
0 0 1 1 0
1 0 1 0 0
没有只有一个1的行或列,因此我们开始赋值。假设我们遵循回溯算法,直到(在步骤1中)将第4列指定给第1行。我们将第1行和第4列中的其他条目设置为x,以表明它们已被分配:

               Step 1        Step 2
1 0 0 1 0 ==> x x x 1 x     x x x 1 x
0 1 1 0 1     0 1 1 x 1 ==> x x 1 x 1
1 1 0 0 1     1 1 0 x 1     1 1 x x 1
0 0 1 1 0     0 0 1 x 0     0 0 x x 0
1 0 1 0 0     1 0 1 x 0     1 0 x x 0
在步骤2中,我们将第3列指定给第2行,并将行和列设置为assigned

请注意,在第4行中,我们没有剩余的1,因此不可能通过此赋值获得有效的解决方案。我们可以立即回溯,为第2行和第1行尝试不同的赋值

原始(错误)答案 每一个可能的nxn矩阵,每一行和每一列中正好有一个1,其余的0是单位矩阵的置换。也就是说,对于n=5,您可以通过交换矩阵的行(或相当于列)来获得此类型的每个有效矩阵:

1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
例如,如果将最后一行交换为行,则会得到:

1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 0 1
0 0 0 1 0
要自动生成所有可能的有效矩阵,首先为单位矩阵的每一行指定一个索引,例如从上到下的1-5:

1- 1 0 0 0 0
2- 0 1 0 0 0
3- 0 0 1 0 0
4- 0 0 0 1 0
5- 0 0 0 0 1

然后,您只需生成所有的n!{1,2,3,4,5}的可能置换。{1,2,3,5,4}的排序将给出上面的第二个矩阵。

这是一个二部匹配问题

考虑一个二部图,其中一个集合(r)中有r个顶点,另一个集合(c)中有c个顶点,其中r和c分别是行数和列数。 在给定矩阵中,当元素
[i,j]
存在时,顶点
i
(在集合R中)和顶点
j
(在集合C中)之间的边为1

如果要查找最大数目为1的矩阵(最大二部匹配),可以使用

O(V.E)


O(sqrt(V.E)

中运行时,使用回溯来减少搜索空间。与经典回溯不同:当你找到第一个解得到所有解时,不要退出。如果你必须生成每一个满意的矩阵,那么就没有摆脱蛮力的复杂性:考虑所有1s组成的输入矩阵。谢谢!如果我理解正确,这只是一个循环,如果第一个循环不是解决方案,我们就找不到一个。如果我们没有解决方案并检查每个可能的解决方案,那么外部循环将如何继续?好的,我将研究某种回溯/蛮力方法的算法,但我猜矩阵的大小是否更大,以及1和0的组合
1 0 0 1 0     1 0 0 1 0     1 0 0 1 0
1 1 0 1 0     1 1 0 1 0 ==> 0 1 0 0 0
1 1 0 0 1 ==> 0 0 0 0 1     0 0 0 0 1
0 0 1 1 0     0 0 1 1 0     0 0 1 1 0
1 0 1 0 0     1 0 1 0 0     1 0 1 0 0
1 0 0 1 0
0 1 1 0 1
1 1 0 0 1
0 0 1 1 0
1 0 1 0 0
               Step 1        Step 2
1 0 0 1 0 ==> x x x 1 x     x x x 1 x
0 1 1 0 1     0 1 1 x 1 ==> x x 1 x 1
1 1 0 0 1     1 1 0 x 1     1 1 x x 1
0 0 1 1 0     0 0 1 x 0     0 0 x x 0
1 0 1 0 0     1 0 1 x 0     1 0 x x 0
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 0 1
0 0 0 1 0
1- 1 0 0 0 0
2- 0 1 0 0 0
3- 0 0 1 0 0
4- 0 0 0 1 0
5- 0 0 0 0 1