此篇整理自李老师上课PPT --- On one way by myself
(1)问题描述
有n个重量分别为{ w1,w2,…,wn}的物品,它们的价值分别为{ v1,v2,…,vn},给定一个容量为W的背包。设计从这些物品中选取一部分物品放入该背包的方案,每个物品要么选中要么不选中,要求选中的物品不仅能够放到背包中,而且重量和为W具有最大的价值。
输入:
3 // n个物品假设为3
16 45 // 第一个物品的重量和价值
15 25 // 第二个物品的重量和价值
15 25 // 第三个物品的重量和价值
30 // 背包容量W
输出:
0 1 1 // 第几个物品选中则为1,不选中则为0
50 // 最大价值
(2)回溯法与分支限界法比较(先区别这两个)
方法 | 解空间搜索方式 |
存储结点的数据结构 |
结点存储特性 |
常用应用 |
---|---|---|---|---|
回溯法 |
深度优先 |
栈 | 活结点的所有可行子结点被 遍历后才从栈中出栈 |
找出满足条件的所有解 |
分枝限界法 |
广度优先 |
队列,优先队列 |
每个结点只有一次成为活结点的机会 |
找出满足条件一个解或者特定意义的最优解 |
首先声明:此两种都有解空间树,问题的解空间树是虚拟的,并不需要在算法运行时构造一棵真正的树结构,然后再在该解空间树中搜索问题的解,而是只存储从根结点到当前结点的路径。
例如:以下求集合{a,b,c}的幂集的解空间树:
第一层为空,第二层为a的选择(左子树)与不选择(右子树),第三层为b的选择(左子树)与不选择(右子树),第四层为c的选择(左子树)与不选择(右子树);求解过程分为3步,分别对a、b、c元素做决策,该解空间的每个叶子结点都构成一个解(很多情况并非如此);在一个解空间中搜索解的过程构成搜索空间,上图中所有叶子结点都是解,所以该问题的解空间和搜索空间相同。
再比如:下图是四皇后问题的搜索空间,图中每个状态由当前放置的皇后的行列号构成。它给出了四皇后问题的全部搜索过程,只有18个结点,其中标有X号的结点无法继续扩展。
(1,*,*,*)表示第一行第一列放个皇后,其他待搜索;(2,4,1,3)表示第一行第二列、第二行第四列、第三行第一列和第四行第三列各放一个皇后,构成一个解;(3,1,4,2)表示第一行第三列、第二行第一列、第三行第四列和第四行第二列各放一个皇后,构成另一个解;
最后说明,活节点:指自身已生成但其孩子结点没有全部生成的结点;扩展节点:是指正在产生孩子结点的结点。
死节点:指由根结点到该结点构成的部分解不满足约束条件,或者其子结点已经搜索完毕
(3)回溯法
就是回退,如四皇后问题,最左侧,放完第一行第一列和第二行第三列后,无法再向下扩展,则向父节点回退,父节点如果还有向下扩展的其他节点则扩展,不能扩展则再向上回退;代码的世界也有哲学,前进的道路走不通时,是深邃骇人的断崖?是飞流急湍的河流?于我何干,我潇洒回退你耐我何?
回溯法搜索解空间时,通常采用两种策略避免无效搜索,提高回溯的搜索效率: