回溯法:0-1背包问题

问题描述

给定n种物品和一背包。 物品i的重量是w_i, 其价值为v_i,背包的容量为 c。 问应该如何选择装入背包中的物品,使得装入背包中物品的总价值最大?注意物品不重复!

实例:物品价值V={12, 11, 9, 8}, 物品重量W={8, 6, 4, 3}, 背包容量c=13

结点:向量(x_1,x_2,...,x_k) ( 子集的部分特征向量)

搜索空间: 子集树2^n片树叶

其中两个可行解为:

<0,1,1,1>:x_1=0,x_2=1,x_3=1,x_4=1\\ <1,0,1,0>:x_1=1,x_2=0,x_3=1,x_4=0

回溯法模版回顾 

参考文章:代码随想录

回溯法解决的问题都可以抽象为树形结构,是的,我指的是所有回溯法的问题都可以抽象为树形结构!

因为回溯法解决的都是在集合中递归查找子集,集合的大小就构成了树的宽度,递归的深度,都构成的树的深度

递归就要有终止条件,所以必然是一棵高度有限的树(N叉树)。

void backtracking(参数) {if (终止条件) {存放结果;return;}for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {处理节点;backtracking(路径,选择列表); // 递归回溯,撤销处理结果}
}

实现代码

终止条件代码

public static void backtracking(int n,  int startIndex) {if (startIndex>=n){//此时startIndex越界了if (getPathSum()<=c){result.add(new ArrayList<>(path));return;}return;}//再加后面任意一个就肯定不够了if (getPathSum()<=c&&(getPathSum() + items_min_weight[startIndex]) > c) {//        if (getPathSum()<c) {result.add(new ArrayList<>(path));return;}for (int i = startIndex; i < n; i++) {path.add(i);backtracking(n,  i + 1);path.removeLast();}

最终代码(含注释)

需要注意的是这里的可行,是再加上未选中的任意一项就>背包容量C

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;public class KnapsackProblem {static List<List<Integer>> result = new ArrayList<>();static LinkedList<Integer> path = new LinkedList<>();static int N = 4;//    static int[] items_weight = new int[N];static int[] items_weight = {8, 6, 4, 3};//    static int[] items_value = new int[N];static int[] items_value = {12, 11, 9, 8};//每个items_min_weight(对应下标为i)的值为min{items_weight[i],...,items_weight[N-1]}static int[] items_min_weight = new int[N];//c为背包的容量static int c=13;public static void main(String[] args) {items_min_weight[N - 1] = items_weight[N - 1];int min = items_min_weight[N - 1];for (int i = items_weight.length - 2; i >= 0; i--) {if (items_weight[i] < min) {min = items_weight[i];}items_min_weight[i] = min;}backtracking(N,  0);System.out.println("可行解有:");result.forEach(System.out::println);//要是想求最优解,直接对每个可行解对应重量求和,之后取最大一个就好啦}public static void backtracking(int n,  int startIndex) {if (startIndex>=n){//此时startIndex越界了if (getPathSum()<=c){result.add(new ArrayList<>(path));return;}return;}//再加后面任意一个就肯定不够了if (getPathSum()<=c&&(getPathSum() + items_min_weight[startIndex]) > c) {//        if (getPathSum()<c) {result.add(new ArrayList<>(path));return;}for (int i = startIndex; i < n; i++) {path.add(i);backtracking(n,  i + 1);path.removeLast();}}public static int getPathSum() {int sum = 0;for (int i = 0; i < path.size(); i++) {sum += items_weight[path.get(i)];}return sum;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/417982.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

不用VBA,如何表格中写公式实现汉字转拼音?

Excel网络函数库自2018年发布以来&#xff0c;我们几乎每天都在帮助用户解决各种办公自动化问题。解决的问题多了&#xff0c;慢慢的我们对用户的业务场景、问题来源、困难诉求有了基本认识。为了更好的帮助大家&#xff0c;未来&#xff0c;我们将对不同职业的办公效率改善问题…

(蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)

能够表示为某个整数的平方的数字称为“平方数 虽然无法立即说出某个数是平方数&#xff0c;但经常可以断定某个数不是平方数。因为平方数的末位只可能是:0,1,4,5,6,9 这 6 个数字中的某个。所以&#xff0c;4325435332 必然不是平方数。 如果给你一个 2 位或 2 位以上的数字&am…

Pandas中不同类型的join操作

Pandas模块包含各种功能&#xff0c;可以在数据框上执行各种操作&#xff0c;如join&#xff0c;concatenate&#xff0c;delete&#xff0c;add等。在本文中&#xff0c;我们将讨论可以在Pandas数据框上执行的各种类型的join操作。Pandas中有五种类型的Join。 为了理解不同类…

systemverilog/verilog文件操作

1、Verilog文件操作 Verilog具有系统任务和功能,可以打开文件、将值输出到文件、从文件中读取值并加载到其他变量和关闭文件。 1.1 、Verilog文件操作 1.1.1、打开和关闭文件 module tb; // 声明一个变量存储 file handler integer fd; initial begin // 以写权限打开一个文…

编译和链接(翻译环境:预编译+编译+汇编+链接​、运行环境)

一、翻译环境和运行环境​ 在ANSI C的任何一种实现中&#xff0c;存在两个不同的环境。​ 第1种是翻译环境&#xff0c;在这个环境中源代码被转换为可执行的机器指令。​ 第2种是执行环境&#xff0c;它用于实际执行代码。​ VS中编译器&#xff1a;cl.exe &#xff1b;Linux中…

linux sudo指令提权

sudo指令 sudo 是在linux中用于以超级用户&#xff08;root&#xff09;权限执行命令的命令。它允许普通用户在执行特定命令时提升其权限&#xff0c;以完成需要超级用户权限的任务。sudo 的名称是 "superuser do" 的缩写。 格式 接受权限的用户登陆的主机 &#xff…

Python自动化测试【selenium面试题】

一、selenium中如何判断元素是否存在&#xff1f; expected_conditions模块提供了16种判断方法&#xff0c;以下方法是判断元素存在DOM中&#xff1a; presence_of_element_located """ An expectation for checking that an element is present on the DOM of…

【网站项目】基于ssm的青大校园预点餐系统

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

算法通关村番外篇-LeetCode编程从0到1系列五

大家好我是苏麟 , 今天带来算法通关村番外篇-LeetCode编程从0到1系列五 . 数学 1523. 在区间范围内统计奇数数目 描述 : 给你两个非负整数 low 和 high 。请你返回 low 和 high 之间&#xff08;包括二者&#xff09;奇数的数目。 题目 : LeetCode 1523. 在区间范围内统计奇…

目标检测数据集 - 跌倒检测数据集下载「包含VOC、COCO、YOLO三种格式」

数据集介绍&#xff1a;跌倒检测数据集&#xff0c;真实场景高质量图片数据&#xff0c;涉及场景丰富&#xff0c;比如交通事故跌倒、打架跌倒、运动跌倒、楼梯跌倒、生病跌倒、遮挡行人跌倒、严重遮挡行人跌倒数据&#xff1b;适用实际项目应用&#xff1a;公共场所监控或室内…

存储的基本架构

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、存储的需求背景二、自下而上存储架构总结 一、存储的需求背景 1、人的身份信息需要存储 这种信息可以用关系型数据库&#xff0c;例如mysql&#xff0c;那种表…

【2024最新】如何有效搭建自动化测试框架?

前言 最近好多小伙伴都在说接口自动化测试&#xff0c;那么究竟什么是接口自动化测试呢&#xff1f;让我们一起往下看就知道了&#xff0c;首先我们得先弄清楚下面这个问题。 为什么要做&#xff08;自动化&#xff09;接口测试&#xff1f; 1、由于现在各个系统的复杂度不断…