一、问题描述
给定一个最大的总切割目标石块,再给定一系列我们需要的样板石块。寻找切割方法使得我们从目标石块上切割出的所需样板石块的面积和最大,即对目标石块的利用率最高。限制切割为一刀切,即一次切割必须把一块石板一分为二,不能只切一段。
左边为目标石块W=8,L=4,右边为样板石块,一共四块。现在我们讨论每种样板石块只切割一块(后续通过输入可以切割k块)。所谓一刀切的意思就是,比如我先从8X4中切割4X3这个石块。第一刀我按照W=4来切,于是分成了两块4X4的石板,第二刀从其中一块石板中按L=3来切,于是分成了一块4X3和一块4X1的石块,如图。
二、算法设计
将所需的样板模块按照面积从大到小进行排序,每次取最大的那块进行切割,在数据量非常大的情况下,单步的最优利用率可能导致全局的最优利用率。进行递归切割,在递归切割的前提下进行回溯,利用限界函数来缩小时间复杂度。
回溯算法的伪代码为,
Backtrck(i)
if i > n then #到达叶节点
if cs > bests then bests = cs
else
if C(i) <= S then #走1分支
cs = cs + s[i]
Backtrck(i+1)
cs = cs - s[i]
if B(i) > bests then #不满足剪支条件可以走0分支
Backtrak(i+1)
其中C(i) = 当前要切割的样板石块的面积,S = 当前剩余可以切割的石块中最大的石块面积,如果当前要切割的面积小于剩余可以切割石块中的最大面积,说明当前石块可以被切割(走1分支)。B(i)= 当前要切割的样板石块的后面i+1,...n块样板石块的面积和,意思为,如果把剩下所有样板石块都切割完成,得到的切割总面积还小于当前已经得到的一个最好解(bests),这时就不用再走0分支,往下递归,因为再走0分支往下递归,也无法得到更好的解,这就叫满足剪支函数。反之,不满足剪支函数,也就是在当前走0分支可能得到