使用最小的行和列切换将NxN二进制矩阵转换为零矩阵

时间:2009-09-28 21:19:36

标签: algorithm matrix

这是我发布的关于将一个NxN二进制矩阵转换为另一个的问题。我问的问题是代码挑战问题。但是,How to do matrix conversions by row and columns toggles?提出了类似的问题。我经历了那个主题,并且已经了解了如何解决这个问题。 我在这里重申一下这个问题。

“我想编写代码来解决以下问题。我打算使用C,C ++,Java或Python,这取决于哪个允许更方便的解决方案。 给定两个N×N(1 <= N <= 2000)个二进制矩阵(每个元素的元素为1或0的矩阵),A和B.问题是使用最小数量的A将A变换为B.允许的操作。 允许的操作是:
1.我们可以切换一行,这将切换该行中的所有值,即它将在该行中更改1到0和0到1 2.我们可以切换一个列,用于切换该列中的所有值,即在该列中将1更改为0,将0更改为1。 如果无法解决问题,我们打印-1“

但是,我有以下疑问。

我知道找到将A变换为B所需的最小切换次数的第一步是计算A XOR B.结果中的1是必须切换的位置,换句话说,XOR B必须使用最小数量的行和列切换转换为零矩阵。但是,我不清楚如何使用最小数量的行和列切换将A XOR B转换为零矩阵。有人可以对此有所了解吗?

谢谢。

2 个答案:

答案 0 :(得分:5)

相当容易的任务。

首先,我们应该了解多次切换行或列没有任何意义。为了更好地理解,我们表示这样的状态:每个单元格中有0或1,并且总是以模2的形式得到和的结果:

final[i,j] = initial[i,j] + row_switched[i] + column_switched[j]  (mod 2)

其中row_switchedcolumn_switched是我们切换第i行和第j列的次数。现在很清楚,它们的值应为0或1,以获得最少数量的开关。

但这实际上是......一个方程组!我们知道初始状态(给定),我们知道最终状态(零),我们只需要针对r[i]c[j]解决系统问题!

不幸的是,由于模数而且因为它不包含隐含在r[i]c[j](0或1)上的约束,所以它仍然很复杂。


让我们在没有模数的情况下重写这些条件:

row_switched[i] + column_switched[j] = 1  (if initial[i,j] = 1)
row_switched[i] - column_switched[j] = 0  (if initial[i,j] = 0)

为每个单元格编写了这个,我们得到了一个过度定义的N ^ 2方程组。让我们用以下方法解决它。很明显,如果我们知道row_switched[0]的值,那么我们就会知道整个column_switched[]数组的值,因为它们是由方程明确推导出来的,其中row_switched[0]参与其中。然后,很容易推断每一行的价值。

但我们只有row_switched[0]的两个变体:0和1.让我们尝试每个变体(参见下面的内容),并为每个变量计算两个数组!然后我们应该检查所有方程式是否,并选择满足整个系统且开关少的两组中的一组。

如果两者都不满足,那么,它是无法解决的。试着解决这个问题,呵呵:

0 1
0 0

这样就完成了解决方案。我希望你只是为了尝试而做一个+1。 :)


关于为什么这是最不可能的开关数量的问题。实际上,任何有效数量的开关都应满足上面概述的方程组(0和1作为值的约束)。但是该系统只有两个以上的解决方案,我们在上面的算法中找到它们。所以,上面的算法肯定会找到最小的算法。


注意: 它对我来说似乎,我们只能尝试其中一个。如果一个人通过了系统,另一个人也应该通过。一组是对另一组的否定,所以我们只选择开关号较少的组。开关总和为2N。但是这只似乎并且不如其他部分清晰。

答案 1 :(得分:2)

让我再次尝试在How to do matrix conversions by row and columns toggles?中解释我的答案结束。

如果可能的话,我们已经减少了通过切换将矩阵转换为零矩阵的问题。首先要注意的是,如果我们想要一个最小的答案,我们永远不会多次切换一行或一列,因为两次切换行/列与不切换开始相同 - 这是身份的结果(P XOR 1)XOR 1 = P。

让我们看看第一行。第一行中的每一个都必须切换为0.我们可以通过在第一行中使用1切换每列来实现,我们可以切换第一行,交换1和0,以及然后将每个新的1切换回0.并且(假设没有切换对)那些是两组操作,导致第一行减少到全0。

此时,请查看其他行。如果任何一行有0或1的混合,你就完成了,问题就不可能了;如果没有列切换,则无法使行全0,并且会在第一行中销毁0。 OTOH,如果每隔一行都是0或全1,那么你只剩下行切换​​。

最后一步是因为有2N可能的切换,并且切换不会成为两种解决方案的一部分。对于列切换,应该立即从上面清楚地看出这一点;对于行切换,请注意在一组列切换之后全部为0的行将在另一组列切换之后全部为1。因此,在计算了一组K切换之后,另一组的大小将为2N-K切换。