回溯法解0/1背包问题
来源:互联网 发布:ug编程怎么加刀补 编辑:程序博客网 时间:2024/06/06 08:38
背包问题(Knap sack problem)是一种组合优化的NP完全问题。问题可以描述为:给定一组物品,每种物品都有自己的重量和价值,在限定的总重量内,我们如何选择,才能使得物品的总价值最高。问题的名称来源于如何选择最合适的物品放置于给定背包中。
0/1背包问题是背包问题的一个特例,在选择物品时只有两种选择,选或不选.解决0/1背包问题就是一个寻找最优解的过程,可以使用动态规划的方法解决.当然最简单的方法就是枚举,列出所有的解,然后计算满足约束的解中最优的解,其实我们可以在枚举的过程中,通过一定的筛选方法去掉那些不可能的解.再进一步思考我们在枚举的过程中是否可以使用一个二叉树来表示选择的过程,这不就是决策树吗?!!通过一定的筛选其实就是剪枝的过程,那么到底满足什么条件时才进行剪枝呢?这个时候约束条件就派上用场了!
用
目标是求价值最大:
贪心算法中,我们按照单位价值非递减的顺序排列即:
代码如下:
def boundF(self, cp, cw, k, M): """ :param cp: :param cw: :param M: :return: maxValue """ b = cp c = cw for i in range(k, self._n): c += self._weight[i] if c < M: b += self._value[i] else: return b + (1 - (c-M)/self._weight[i])*self._value[i] return b
有了裁剪分支的上界函数后,就可以通过回溯的方法遍历解的空间树,如果一个点满足约束条件就继续深度优先搜索,不满足的时候判断是否需要截枝进行回溯,思路还是简单的,具体过程如下
def backKnap(self, M): cw = 0 cp = 0 k = 0 fp = -1 Y = [0 for i in range(self._n)] X = [0 for i in range(self._n)] while True: while k < self._n and cw + self._weight[k] <= M: cw = cw + self._weight[k] cp = cp + self._value[k] Y[k] = 1 k += 1 if k > self._n - 1: fp = cp k = self._n -1 X = Y[:] self._solution.append(X) else: Y[k] = 0 while self.boundF(cp, cw, k+1, M) <= fp: # 必须是k+1,若是k第一次探索, fp=-1,boundF()永远不会小于等于-1,会死循环 while k != -1 and Y[k] != 1: k -= 1 if k == -1: return X Y[k] = 0 cw -= self._weight[k] cp -= self._value[k] k += 1
上述的程序输出最优解,同时用self._solution保存了所有遍历到叶子节点的解.
完整代码:BackKnap
- 回溯法解0-1背包问题
- 回溯法解0-1背包问题
- 回溯法解0/1背包问题
- 回溯法解0-1背包问题
- 回溯法解0-1背包问题
- 0-1背包问题(回溯法)
- 0-1背包问题(回溯法)
- 0/1背包问题-回溯法
- 回溯法:0-1背包问题
- 0-1背包问题(回溯法)
- 回溯法求解0/1背包问题
- 回溯法求解0-1背包问题
- 回溯法 0-1背包问题
- 回溯法解决0-1背包问题
- 0-1背包问题(回溯法)
- 回溯法之0-1背包问题
- 【回溯法】0-1背包问题
- 0-1背包问题回溯法
- maven下载地址记录
- 黑马程序员-Java集合框架
- 如何让 UITableView 的 headerView跟随 cell一起滚动
- mysql数据库使用常见错误
- 基于innobackupex的mysql备份脚本
- 回溯法解0/1背包问题
- java常见异常
- 单身快乐
- linux or unix vi编辑器常用命令
- 二分k-均值算法
- Android Process 进程通信(一)
- MonoDevelop 常用配置设置
- Python + OpenCV颜色空间(Color Space)
- thrift 基本概念