如果您有一个1和0的二进制矩阵,并且您能够切换列(将列中的所有1更改为0,将所有0更改为1),您如何找到“纯”行的最大数量列切换的所有可能组合? “pure”表示该行全为0或全1。
例如:
1 0
1 0
1 1
您可以切换任一列以获得“纯”的2行,这是您可以做的最好的(切换两者并不是更好),因此您返回2(“纯”行的最大数量)。
我似乎无法找到一种有效的方法来做到这一点。我到目前为止唯一的方法是使用一堆循环和暴力并通过检查行的总和是0(全0)还是N(行中元素的数量)来检查相同性。 / p>
答案 0 :(得分:4)
从OP澄清之后,最大纯行问题是以找到切换后变为00 ... 0或11 ... 1的最大行数。我已相应更新了我的解决方案。
请注意,我们有以下事实:
如果两行 r i 且 r j 在切换后减少为纯行,那么我们必须以 r i = r j 开始。
如果 r i ≠ r j 和 r i < / sub> 重叠 r j (即它们的一些相应列是相同的),然后它们都无法映射到纯行。
以上两个事实直接来自以下观察:
Max number of "pure" rows is the same as the max number of identical rows
我们声称构成最大纯问题解的所有行必须在矩阵M中相同。
假设给出了一个m-by-n矩阵 M ,我们找到了max-pure行问题的解决方案。让行 r i 和 r j 是两个任意行,在切换后会减少为纯行。
观察对列进行所有必要的切换操作后(由σ 1 表示,σ 2 ,...,σ k ), r i 和 r j 都是“纯”行。即我们有以下内容:
σ1(σ2(...(σk(ri)...)) = σ1(σ2(...(σk(rj)...)) = 00...0
或
σ1(σ2(...(σk(ri)...)) = σ1(σ2(...(σk(rj)...)) = 11...1
因此,在应用所有这些切换操作后, r i 和 r j 将彼此相等。如果我们撤消最后一次切换(即我们切换这些行的相同列条目),显然两个 r i 和< em> r j 仍将映射到相同的输出。即我们有以下内容:
σ2(σ3(...(σk(ri)...)) = σ2(σ3(...(σk(rj)...))
如果我们继续撤消切换操作,我们可以得出结论 r i = r j 。换句话说,如果从max-pure问题的解决方案中选择任意行,则这些行在开头必须相同。
给定一行 r i ,如果它可以减少到纯行,比如00 ... 0,那么我们知道另一行 r如果 r i 与 r j重叠,则 j 不能简化为11 ... 1 sub> (来自上面的事实2)。我们只能希望另一行 r k 与 r i 不重叠,以减少到11 .. 0.1。
从前面的想法,我们可以有以下简单的算法来解决最大纯行问题。
我们首先扫描矩阵M的行,然后找到矩阵的所有唯一行(由 s 1 表示,s 2 ,...,s k )。我们让count(si)
表示 s i 出现在M中的次数。
然后我们遍历所有对( s i ,s j )以确定最大纯行数,如下所示:
int maxCount = 0;
for each row si:
for each sj ≠ si:
if (sj overlaps si)
continue;
else
if (count(si) + count(sj) > maxCount)
// We have found a better pair
maxCount = count(si) + count(sj);
return maxCount;
我们正在做O(n)
在内部for循环中工作(用于逐项检查两行是否重叠),并且在最坏情况下循环超过O(m2)
行,因此运行时间算法的结果是O(nm2)
。
答案 1 :(得分:0)
也许我错过了一些东西,但是快速排下这些行应该回答你的问题。
从顶行开始,根据需要翻转每一列,直到顶行全部为T.计算纯行数。对每隔一行重复一次,查找计数是否大于前一行。
您不需要反转整个矩阵,因此每一行都是F,计数将是相同的。
最坏情况下的运行时间为O(nm)
。