解题步骤
1.使用算法的基本介绍
2.具体解题思路
3.代码或伪代码
一. 蛮力法
- 蛮力法(穷举法或枚举法)是一种简单直接地解决问题的方法,常常直接基于问题的描述,所以,蛮力法也是最容易应用的方法。蛮力法所依赖的最基本技术是扫描技术,依次处理元素是蛮力法的关键,依次处理每个元素的方法是遍历。
- 对于有n种可选物品的0/1背包问题,其解空间由长度为n的0-1向量组成,可用子集数表示。在搜索解空间树时,深度优先遍历,搜索每一个结点,无论是否可能产生最优解,都遍历至叶子结点,记录每次得到的装入总价值,然后记录遍历过的最大价值。
二.递归与分治法
-
递归算法是直接或间接地调用自身的算法。用函数自身给出定义的函数称为递归函数。
-
分治法 是将一个难以直接解决的大问题,分割成一些规模较小的相同问题,这些子问题互相独立且与原问题相同,采用递归的方式,分而治之。最后将子问题的解决结果合并,得到问题的解
-
0、1背包问题不能使用分治法解决,应为分解的子问题并不相同
三.动态规划
-
动态规划算法,其基本思想也是将待求解问题分解成若干个子问题,经分解得到的子问题往往不是相互独立的,先求解子问题,然后从这些子问题的解得到原问题的解。该算法的有效性依赖于问题本身所具有的两个重要性质:最优子结构性质和子问题重叠性质。
-
对于每个物品我们可以有两个选择,放入背包,或者不放入,有n个物品,故而我们需要做出n个选择,于是我们设f[i][v]表示做出第i次选择后,所选物品放入一个容量为v的背包获得的最大价值。
①如果放入第i件物品,则f[i][v] = f[i-1][v-w[i]]+p[i],表示,前i-1次选择后所选物品放入容量为v-w[i]的背包所获得最大价值为f[i-1][v-w[i]],加上当前所选的第i个物品的价值p[i]即为f[i][v]。
②如果不放入第i件物品,则有f[i][v] = f[i-1][v],表示当不选第i件物品时,f[i][v]就转化为前i-1次选择后所选物品占容量为v时的最大价值f[i-1][v]。
动态规划的选择方式:f[i][v] = max{f[i-1][v], f[i-1][v-w[i]]+p[i]}。
四.贪心算法
-
贪心算法通过一系列的选择来得到问题的解。它所做的每一个选择都是当前状态下局部最好的选择,即贪心选择。对于一个具体的问题,能用贪心算法求解的问题一般具有两个重要的性质:贪心选择性质和最优子结构性质。
- 贪心选择性质:所求问题的整体最优解可以通过一系列局部最优的选择
- 最优子结构性质:一个问题的最优解包含其子问题的最优解
-
对于0-1背包问题,贪心算法之所以不能得到最优解是因为在这种情况下,它无法保证最终能将背包装满,部分闲置的背包空间使每千克背包空间的价值降低了。事实上,在考虑0-1背包问题时,应比较选择该物品和不选择该物品所导致的最终方案,然后再做出最好的选择
五.回溯法
- 回溯法从根结点出发,以深度优先方式搜索整个解空间。这个开始结点称为活结点,同时也称为当前的扩展结点。在当前的扩展结点处,搜索向纵向移至一个新结点。这个新结点就成为新的活结点,并成为当前扩展结点。如果在当前的扩展结点处不能再纵向移动,则这个结点就是死结点。此时,应该往回移动(回溯)至最近的一个活结点处,并使这个活结点成为当前扩展结点。回溯法以这种工作方式递归地在解空间中搜索,直至找到所要求的解或解空间中已无活结点为止。
- 对于有n种可选物品的0/1背包问题,其解空间由长度为n的0-1向量组成,可用子集数表示。在搜索解空间树时,只要其左儿子结点是一个可行结点,搜索就进入左子树。当右子树中有可能包含最优解时就进入右子树搜索。
六.分支限界法
- 在分支限界法中,每一个活结点只有一次机会成为扩展结点。活结点一旦成为扩展结点,就一次性产生其所有孩子结点。在这些孩子结点中,导致不可行解或导致非最优解的孩子结点被舍弃,其余孩子结点被加入活结点表中。此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。这个过程一直持续到找到所需要的解或活结点表为空时为止。
- 首先,要对输入数据进行预处理,将各物品依其单位重量价值从大到小进行排列。在下面描述的优先队列分支限界法中,节点的优先级由已装袋的物品价值加上剩下的最大单位重量价值的物品装满剩余容量的价值和。算法首先检查当前扩展结点的左儿子结点的可行性。如果该左儿子结点是可行结点,则将它加入到子集树和活结点优先队列中。当前扩展结点的右儿子结点一定是可行结点,仅当右儿子结点满足上界约束时才将它加入子集树和活结点优先队列。当扩展到叶节点时为问题的最优值。