C 求给定二进制数据的最大面积
我在描述查找二进制数据的最大矩形区域的算法时遇到了一个问题,其中1的出现频率是0的k倍。数据总是n^2位,如下所示: 例如,n=4的数据如下所示:C 求给定二进制数据的最大面积,c,algorithm,optimization,binary,brute-force,C,Algorithm,Optimization,Binary,Brute Force,我在描述查找二进制数据的最大矩形区域的算法时遇到了一个问题,其中1的出现频率是0的k倍。数据总是n^2位,如下所示: 例如,n=4的数据如下所示: 1010 01 01 10101 k的值可以是1。。j(k=1表示0和1的数量相等)。 对于上述数据示例和k=1,解决方案为: 101020速度太慢了。你能告诉我该如何解决这个问题吗 正如RBerteig所提出的,这个问题也可以这样描述:“在给定的正方形位图中,通过一些任意过程将单元格设置为1或0,找到最大的矩形区域,其中1和0以指定的比例出现,k
1010
01
01
10101
k的值可以是1。。j(k=1表示0和1的数量相等)。
对于上述数据示例和k=1,解决方案为: 101020速度太慢了。你能告诉我该如何解决这个问题吗
正如RBerteig所提出的,这个问题也可以这样描述:“在给定的正方形位图中,通过一些任意过程将单元格设置为1或0,找到最大的矩形区域,其中1和0以指定的比例出现,k.”这仍然是蛮力,但您应该注意的是,对于新的
i*j
矩形,您不必从头开始重新计算所有内容。相反,对于每个可能的矩形大小,您可以在n*n
网格上一步一步地移动矩形,减少不再在矩形内的位的计数,并增加新进入矩形的位的计数。您可以将这一点与改变矩形大小结合起来,并尝试找到移动和调整矩形大小的最佳模式。如果正确实施,Bruteforce在n<100的情况下应该可以做得很好:下面的解决方案具有O(n^4)时间和O(n^2)内存复杂性。在现代PC机上,10^8操作应该在1秒以内(特别是考虑到每个操作都非常便宜:几乎没有加法和减法)
一些观察
[LI]有O(n 4)子矩形要考虑,每个都可以是一个解。
[i0..i1]x[j0..j1]
。即,它占用i0和i1之间的行和j0和j1之间的列。让count_one
作为计算子矩形中1个数的函数
这是主要观察结果:
count_ones([i0..i1]x[j0..j1]) = count_ones([0..i1]x[0..j1]) - count_ones([0..i0 - 1]x[0..j1]) - count_ones([0..i1]x[0..j0 - 1]) + count_ones([0..i0 - 1]x[0..j0 - 1])
与实际例子相同的观察结果:
AAAABBB
AAAABBB
CCCCDDD
CCCCDDD
CCCCDDD
CCCCDDD
如果我们需要在D子矩形(3x4)中找到1的数量,我们可以通过计算整个矩形(A+B+C+D)中的1的数量,减去(A+B)矩形中的1的数量,减去(A+C)矩形中的1的数量,再加上(A)矩形中的1的数量来实现<代码>(A+B+C+D)-(A+B)-(A+C)+(A)=D
因此,我们需要为每个i
和j
表求和
,它们包含子矩形[0..i][0..j]
您可以在O(n^2)中创建此表,但即使是直接填充它的方式(对于每个
i
和j
迭代[0..i][0..j]
区域的所有元素)也将是O(n^4)
有了这张桌子
count_ones([i0..i1]x[j0..j1]) = sums[i1][j1] - sums[i0 - 1][j1] - sums[i1][j0 - 1] + sums[i0 - 1][j0 - 1]
因此,时间复杂度O(n^4)达到了。只是一些提示
您可以对这些值施加更好的限制。这一要求导致了条件的改变
N1*(k+1)==S*k
,其中N1
是一个区域中的个数,S=dx*dy
是其表面。
它可以以更好的形式重写:
N1/k==S/(k+1)
因为数字n
和n+1
的最大公约数总是1,所以N1
必须是k
的倍数,dx*dy
必须是k+1
的倍数。它大大减少了可能的解空间,越大的k
越好(对于dx*dy
情况,您需要使用k+1
的素数因子)
现在,因为你只需要拥有这样属性的最大区域的表面,所以明智的做法是从最大的区域开始,移动到较小的区域。通过尝试dx*dy
从n^2
到k+1
满足除数和边界条件,你会很快找到解决方案,比O(n^4)快很多,因为一个特殊的原因:除了特殊构造数组的情况,如果我们假设一个随机输入,在(n-dx+1)*(n-dy+1)
具有表面S
的区域中,S
值中存在N1
的概率将随着S
的减少而不断增加。(较大的k
值将使概率更小,但同时它们将使dx
和dy
对的过滤器更强)
另外,这个问题:,看起来有些相似,也许你会在他们的解决方案中找到一些想法。我不确定我是否理解这个问题。算法应该做什么?算法应该在给定的数据(nxn位)中找到一个矩形扇区,其中“1”的出现频率是“0”的k倍。对于k=1,算法应该找到这样的数据片段,“1”与“0”出现的时间相同。如果数据是1行,我会使用前缀sum,但在这种情况下,我想我不能这样做。这是对问题的正确重述吗?“在给定的正方形位图中,通过一些任意过程将单元格设置为1或0,找到1和0以指定比率出现的最大矩形区域,
k
”对于上面给出的最后一个示例,为什么由完整的三个右侧列组成的矩形不是“解决方案”?值得注意(尽管非常明显)如果比率为k,矩形的面积必须是(k+1)的倍数-这将消除许多矩形。我正在考虑这个解决方案,但当我试图估计步数时,我发现它太复杂了。对于n=200(40000 b