这个问题我们在贪心算法那章讲过了,当时是用的贪心算法,给定载重量让你自由选择装载的货物,尽可能多地装载货物。当时我们是通过优先装载重量最轻的集装箱解决的。
现在题目变形,需要我们找出一个方法把n个集装箱全部装到船上,那么我们应当使用回溯法来解决,由于解空间是无所谓装载的货物序号的,因此这是一个子集树的回溯法问题。其类似于一个01背包问题。
这里涉及到了一个回溯法的重要操作——剪枝
顾名思义,剪枝就是将某段子树从我们的结果遍历中减去。通常是因为当前的结果已经不符合我们的判断条件了(还记得上一节讲到回溯法的算法里总要加上判断条件吗,一个答案的解一定符合我们的条件,不符合的就需要剪枝),如果当前的结果已经不符合我们的条件,比如这题中已经超载了,那么其子树——就相当于再加一个箱子到船上,必然也是超载的,那么从超载开始的这一个结点以及以下的各个子结点必然都不符合我们的解的需求,因此我们就对这个结点进行剪枝,就省去了遍历那些错误结果的时间。
直接看看改进后求最优解的算法
更好的最优解优化可以采用之前学习过的动态规划的思想,最优结构的子结构也应当最优
当且仅当cw>当前最优解bestw才输出,否则输出bestw
(迭代回溯就不看了,总的来说还是递归回溯好懂一点)
另一个老问题,批处理作业调度。之前我们考虑到很多因素,比如尽可能使得几个机器的处理时间相近,寻找最优解结构等方法。现在学习了回溯法就可以简单粗暴一点。
需要满足条件:每个任务都要先在机器1上执行再到机器2执行,最终时长=机器1执行时长+机器2执行时长
如果用回溯法,这就是一个排序树的回溯法问题。我们就深度优先遍历这个排序树,该剪枝的剪枝,寻找最优的解。
借用他人博客的一张图,可以看的更明白
出处:批处理作业调度【回溯算法】_哆啦 AI 梦的博客-CSDN博客_批处理作业调度