我有一个nxm个由非负整数组成的矩阵。例如:
2 3 4 7 1
1 5 2 6 2
4 3 4 2 1
2 1 2 4 1
3 1 3 4 1
2 1 4 3 2
6 9 1 6 4
“投下炸弹”会使目标细胞及其所有八个邻居的数量减少一个,直到最小值为零。
x x x
x X x
x x x
什么样的算法可以确定将所有细胞减少到零所需的最少炸弹数量?
B选项(因为我不是一个细心的读者)
事实上,问题的第一个版本并不是我要寻找的答案。我没有仔细阅读整个任务,有额外的约束条件,让我们说:
那么简单的问题是,当行中的序列必须是非递增的:
8 7 6 6 5是可能的输入序列
7 8 5 5 2是不可能的,因为7 -> 8在一个序列中增长。
也许为“简单”的问题找到答案会有助于为更难的问题找到解决方案。
PS:我相信当我们有几个相同的情况需要最少的炸弹来清除上面的线时,我们会选择在“左侧”使用最多炸弹的一个。还有什么证据是正确的吗?
在这里,线性规划方法似乎非常有用。
设Pm x n为包含位置值的矩阵:
现在定义一个炸弹矩阵B(x, y)m x n,其中1≤x≤m, 1≤y≤n如下所示
以这样一种方式
例如:
所以我们正在寻找一个矩阵Bm x n = [bij]
可以定义为炸弹矩阵的和:
(qij将是我们在pij位置投放的炸弹数量)
pij - bij≤0(为了更简洁,我们称之为P - B≤0)
而且,B应该使和最小。
我们也可以把B写成前面的丑矩阵:
由于P - B≤0(即P≤B),我们得到了如下线性不等式系统:
qmn x1定义为
PMN x 1定义为
我们可以说我们有一个方程组是smnxmn这个矩阵要倒转来解方程组。我自己没有扩展它,但我相信在代码中应该很容易做到。
现在,我们有一个最小的问题可以表述为
I believe it is something easy, almost trivial to be solved with something like the simplex algorithm (there is this rather cool doc about it). However, I do know almost no linear programming (I will take a course about it on Coursera but it is just in the future...), I had some headaches trying to understand it and I have a huge freelance job to finish so I just give up here. It can be that I did something wrong at some point, or that it can't go any further, but I believe this path can eventually lead to the solution. Anyway, I am anxious for your feedback.
(特别感谢这个神奇的网站从LaTeX表达式创建图片)
你的新问题,有跨行不递减的值,很容易解决。
Observe that the left column contains the highest numbers. Therefore, any optimal solution must first reduce this column to zero. Thus, we can perform a 1-D bombing run over this column, reducing every element in it to zero. We let the bombs fall on the second column so they do maximum damage. There are many posts here dealing with the 1D case, I think, so I feel safe in skipping that case. (If you want me to describe it, I can.). Because of the decreasing property, the three leftmost columns will all be reduced to zero. But, we will provably use a minimum number of bombs here because the left column must be zeroed.
现在,一旦左边的列归零,我们只要剪掉最左边的三列现在归零,然后对现在化简的矩阵重复这一步骤。这必须给我们一个最优的解决方案,因为在每个阶段我们使用可证明的最少数量的炸弹。
你可以把这个问题表示成整数规划问题。(这只是解决这个问题的一种可能的方法)
有分:
a b c d
e f g h
i j k l
m n o p
我们可以写出16个方程其中以点f为例
f <= ai + bi + ci + ei + fi + gi + ii + ji + ki
最小化所有索引的总和和整数解。
解当然是这些指标的和。
这可以通过将所有xi设置为边界0来进一步简化,因此在本例中最终得到4+1方程。
问题是没有解决这类问题的简单算法。我不是这方面的专家,但解决这个问题作为线性规划是NP困难。
这是另一个想法:
让我们先给黑板上的每个空格分配一个权重,计算在那里扔炸弹会减少多少数字。如果这个空间有一个非零数,它就得到一个点,如果它的相邻空间有一个非零数,它就得到一个额外的点。如果这是一个1000 * 1000的网格,我们为这100万个空间中的每一个都分配了权重。
然后根据权重对列表中的空格进行排序,并轰炸权重最高的空格。可以这么说,这是我们最大的收获。
在此之后,更新每个空间的重量是受炸弹的影响。这是你轰炸的空间,和它相邻的空间,以及它们相邻的空间。换句话说,任何空间的价值都可能因为爆炸而减少为零,或者相邻空间的价值减少为零。
然后,根据权重重新排序列表空间。由于轰炸只改变了一小部分空间的权重,因此不需要使用整个列表,只需在列表中移动这些空间。
轰炸新的最高权重空间,并重复上述步骤。
这保证了每次轰炸都能减少尽可能多的空格(基本上,它会击中尽可能少的已经为零的空格),所以这是最优的,除非它们的权重是相同的。所以你可能需要做一些回溯跟踪,当有一个平局的顶部重量。不过,只有最高重量的领带重要,其他领带不重要,所以希望没有太多的回溯。
Edit:
Mysticial's counterexample below demonstrates that in fact this isn't guaranteed to be optimal, regardless of ties in weights. In some cases reducing the weight as much as possible in a given step actually leaves the remaining bombs too spread out to achieve as high a cummulative reduction after the second step as you could have with a slightly less greedy choice in the first step. I was somewhat mislead by the notion that the results are insensitive to the order of bombings. They are insensitive to the order in that you could take any series of bombings and replay them from the start in a different order and end up with the same resulting board. But it doesn't follow from that that you can consider each bombing independently. Or, at least, each bombing must be considered in a way that takes into account how well it sets up the board for subsequent bombings.