0-1背包问题(回朔法搜索子集树)

将解空间用一颗完全二叉树表示,用回朔法搜索这颗树:解法1:建立了一个完全二叉树(称子集树),结点中带有需要的信息,深度优先遍历这颗二叉树(递归方法),找到最优解。困难:如何记录当前的路径?解决方案:1、设置一个栈2、在递归调用“深度优先遍历左子树”之前,将0压入栈;在递归调用“深度优先遍历右子树”之前,将1压入栈3、当递归调用出来后,将栈顶元素弹出这样到了页结点的时候,
摘要由CSDN通过智能技术生成

将解空间用一颗完全二叉树表示,用回朔法搜索这颗树:

解法1:建立了一个完全二叉树(称子集树),结点中带有需要的信息,深度优先遍历这颗二叉树(递归方法),

找到最优解。

困难:如何记录当前的路径?

解决方案:1、设置一个栈

2、在递归调用“深度优先遍历左子树”之前,将0压入栈;在递归调用“深度优先遍历右子树”之前,将1压入栈

3、当递归调用出来后,将栈顶元素弹出

这样到了页结点的时候,栈中的元素就是一个解

解法2:(巧妙)不需要建立树的代码,只需要用一个数组存放访问路径,核心代码如下:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
0-1背包问题是一个经典的动态规划问题,可以用回溯求解。以下是算设计: 1. 定义一个最大价值 max_val,初始值为0;定义一个当前价值 cur_val,初始值为0。 2. 定义一个回溯函数 backtrack(cur_weight, cur_val, items, values, weights, max_weight),其中: - cur_weight:当前背包已经装入的物品的重量; - cur_val:当前背包已经装入的物品的价值; - items:已经选择的物品; - values:每个物品对应的价值; - weights:每个物品对应的重量; - max_weight:背包的最大承重。 3. 在回溯函数中,首先判断当前背包的重量是否超过了最大承重,若超过则返回。 4. 然后判断当前价值是否大于最大价值,若大于则更新最大价值。 5. 接下来进行回溯,对于每一个物品,分别进行选择和不选择两种情况: - 若选择该物品,则将该物品的重量和价值加入到 cur_weight 和 cur_val 中,同时将该物品加入到 items 中,并继续向下执行回溯函数; - 若不选择该物品,则直接跳过该物品,继续向下执行回溯函数。 6. 回溯结束后,返回最大价值。 以下是Python代码实现: ```python def backtrack(cur_weight, cur_val, items, values, weights, max_weight): global max_val if cur_weight > max_weight: return if cur_val > max_val: max_val = cur_val for i in range(len(values)): if i not in items: items.append(i) backtrack(cur_weight + weights[i], cur_val + values[i], items, values, weights, max_weight) items.remove(i) def knapsack_01(values, weights, max_weight): global max_val max_val = 0 items = [] backtrack(0, 0, items, values, weights, max_weight) return max_val ``` 可以使用以下代码进行测试: ```python values = [6, 10, 12] weights = [1, 2, 3] max_weight = 5 print(knapsack_01(values, weights, max_weight)) # 输出:22 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值