我正在寻找一种有效的算法(理想情况下,类似C的伪代码)来给出以下分区问题的近似解决方案。给定序列 S = { a_i : i = 1,..., n }和绑定< em> B ,将 S 的分区确定为一些 m 的连续子序列,如下所示。对于每个 k ,让 s _ k 为 k -th子序列的元素之和。分区必须满足:
我知道这与minimum raggedness word wrap algorithm密切相关。我正在寻找一些可以为 n (小于15)的小值提供“足够好”的解决方案,而不会像动态编程那样拉出重型弹药,而且还有比蛮力更快的东西。
答案 0 :(得分:1)
设S代表所有项目的总和,让n为项目数。如果您将项目放在m行上,则每条线上的重量至少为S / m。因为S /m≤B,你得到m≥S/ B.我将从天花板(S / B)开始作为m的值,然后将m增加1直到找到解决方案。
当设置m并给出n时,只需递归搜索正确的边界即可。你可以逐行(递归地)猜测行之间的界限,并在解决方案变得不可行时回溯。如果找到解决方案,则将其存储以供参考,因为它可能是最好的色散方式。最终您选择了最佳解决方案。如果没有解决方案,则将m增加1并重做。
答案 1 :(得分:0)
我最终做了一个简单的回溯搜索。首先,我按照antti.huima的描述计算了 m (该部分非常简单且固定 m )。然后我贪婪地分配了项目(尽可能地按顺序打包每个分区)。最后,我运行了一个回溯算法,为每个分区边界的起始索引分配一个增量,从最后一个分区开始。每个delta_j表示从贪婪的起始位置移动分区 j 的开始的距离。不难显示0 <= delta_j&lt; (每个j的分区j-1的大小)> 1(否则贪婪算法的表现会有所不同)。与将搜索从1填充到 m 的搜索相比,这大大减少了搜索空间。
我认为这种搜索的某种启发式变体是可能的并且会更有效率,但我并没有非常努力地找到它。