计算机算法分析与设计(20)---回溯法(0-1背包问题)

文章目录

    • 1. 题目描述
    • 2. 算法思路
    • 3. 例题分析
    • 4. 代码编写


1. 题目描述

 对于给定的 n n n 个物品,第 i i i 个物品的重量为 W i W_i Wi,价值为 V i V_i Vi,对于一个最多能装重量 c c c 的背包,应该如何选择放入包中的物品,使得包中物品的总价值最大?

2. 算法思路

 1. 将问题转化为:

在这里插入图片描述
 2. 按照上述思路,先将各物品按照单位价值递减的顺序排序,其次进行判断是否在承重范围值内。
 定义: c w cw cw(current weight)表示当前重量, c p cp cp(current price)表示当前价值。
 根节点代表扩展结点 ,其余每一层代表一个物品,越靠近根节点,单位价值越高。选中该物品,即搜索左子树,进行判断。具体执行操作如下所示:

 (1)先计算所有物品的单位价值,将其进行降序排列。

 (2)排列之后,从根节点(扩展节点)出发。

 (3)搜索左子树,判断是否满足约束条件(物品是否装入背包):

       若选中该物品(可行解),cw+=w[i],cp+=p[i],继续向下遍历;直至遇到不可行解时,开始向上回溯,取出最后一个装入的物品,进入右子树。

 (4)进入右子树,首先计算当前节点的上界bound(i):

       若bound(i)小于bestp,剪去右子树,继续向上回溯;否则进行步骤(3)。

 (5)遇到叶子节点,比较当前价值与bestp,若cp>bestp,则bestp进行更新。

 (6)直到遍历完所有的节点(除剪枝部分外)。

3. 例题分析

 1. 例题1(手写):

在这里插入图片描述
在这里插入图片描述
 2. 例题2:假设 n = 3 n=3 n=3(有三件物品),三个物品的重量为 20 、 15 、 10 {20、15、10} 201510,三个物品的价值为 20 、 30 、 25 {20、30、25} 203025,对于一个最大承重为 25 25 25 的背包,求包中物品的组合最大的价值是多少?

在这里插入图片描述
 3. 例题2分析过程:对三件物品分别进行编号 1 , 2 , 3 1,2,3 123。初始情况背包是空的。

 (1)首先我们把 1 1 1 号物品放进背包里,此时背包里只有一件物品,总重量为 0 + 20 = 20 0+20=20 0+20=20,没有超过承重 25 25 25,因此可以将 1 1 1 号物品成功放入背包内。

 (2)接下来尝试把 2 2 2 号物品放入背包内,但是发现包中 1 1 1 号物品和 2 2 2 号物品的重量和为 20 + 15 = 35 20+15=35 20+15=35,超过了承重 25 25 25,因此不能把 2 2 2 号物品放入背包内。

 (3)接着考虑 3 3 3 号物品,此时包中只有 1 1 1 号物品。发现 1 1 1 号物品和 3 3 3 号物品的重量和为 20 + 10 = 30 20+10=30 20+10=30,超过了承重 25 25 25,因此 3 3 3 号物品也不能放入背包内。

 (4)由于只有 3 3 3 件物品,并且对于每一种物品我们都考虑过是否将其放入背包内,也就是找到了一种基本情况。找到一个基本情况后,我们就可以看看包里的物品的总价值了。这里包里只有一个 1 1 1 号物品,因此总价值为 20 20 20

 (5)重点来了!回溯过程:每次找出一种满足条件的基本情况就进行一次回溯,找到最后放入包中的物品并将其取出,接着考虑是否放入编号在这个物品之后的第一个物品。这里我们就把 1 1 1 号物品取出,接下来考虑是否放入 2 2 2 号物品。

 (6)取出 1 1 1 号物品后背包是空的,此时如果放入 2 2 2 号物品,背包总重量为 15 15 15,没有超过背包承重,因此把 2 2 2 号物品放入背包内。

 (7)类似地,考虑将 3 3 3 号物品放入背包内。由于 2 2 2 号物品和 3 3 3 号物品的重量和为 15 + 10 = 25 15+10=25 15+10=25,没有超过承重 25 25 25,因此将其放入背包内。

 (8)由于考虑完了 3 3 3 号物品,因此又找到了一个基本情况,记下此时包里物品的总价值,为 30 + 25 = 55 30+25=55 30+25=55。由于 55 55 55 高于上一种基本情况的总价值,因此将最优解更新为 55 55 55

 (9)进行一次回溯,取出背包中最后放入的物品,也就是 3 3 3 号物品。但是注意:当最后放入背包中的物品恰好是编号最大的物品时,需要额外进行一次回溯。为什么呢?因为编号最大的物品之后已经没有编号更大的物品了,因此没有可以考虑的下一种情况,只能在上一个层面上在进行一次回溯才能产生可能的最优解(此处不必考虑只放入2号物品的情况,因为一定不是最优解,原因可以自己思考一下)。 这里再回溯一次,也就是将倒数第二个放入包中的物品取出来,这里就取出 2 2 2 号物品。先后取出 3 3 3 号物品和 2 2 2 号物品之后包应该处于空的状态。

 (10)上一步中取出了 2 2 2 号物品,因此这一步直接考虑能否放入 3 3 3 号物品,简单的判断后即可得出可以放入,并且同上理也可以得出这是一种基本情况。但是由于包中只有 3 3 3 号物品,总价值为 25 25 25,没有超过当前的最优解 55 55 55,因此将该情况忽略。

 (11)最后一次回溯,取出包中的 3 3 3 号元素。由于此时包已经空了,并且最后一次取出的是编号最大的元素,那么说明算法已经完成了所有情况的遍历,算法终止, 55 55 55 是最优解。

4. 代码编写

// n=5, c=10, w={2, 2, 6, 5, 4}, v={6, 3, 5, 4, 6}的0-1背包问题的最优解和最优值。
#include <iostream>
using namespace std;#define N 10
int w[N]; //重量
int v[N]; //价值
int x[N]; //1表放入背包,0表不放入
int n,c;  //n:物品个数 c:背包的最大容量int cw=0; //当前物品总重
int cv=0; //当前物品总价值int bestp=0;  //当前最大价值
int bestx[N]; //最优解//回溯函数 k表示当前处在第几层做选择,k=1时表示决定是否将第一个物品放入背包
void backtrack(int k)
{//叶子节点,输出结果if(k>n){//找到一个更优的解if(cv>bestp){  //保存更优的值和解bestp = cv;for(int i=1; i<=n; i++)bestx[i] = x[i];}}else{//遍历当前节点的子节点for(int i=0; i<=1; i++){x[k]=i;if(i==0){backtrack(k+1);}else{  //约束条件:当前物品是否放的下if((cw+w[k])<=c){cw += w[k];cv += v[k];backtrack(k+1);cw -= w[k];cv -= v[k];}}}}
}int main()
{cout<<"请输入物品的个数:";cin>>n;cout<<"请输入每个物品的重量及价值:"<<endl;for(int i=1;i<=n;i++){cin>>w[i]>>v[i];}cout<<"请输入背包的限制容量:";cin>>c;backtrack(1);cout<<"最优值是:"<<bestp<<endl;cout<<"(";for(int i=1;i<=n;i++){cout<<bestx[i]<<" ";} cout<<")";return 0;
}

在这里插入图片描述

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

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

相关文章

论文-分布式-并发控制-Lamport逻辑时钟

目录 前言 逻辑时钟讲解 算法类比为面包店内取号 Lamport算法的时间戳原理 Lamport算法的5个原则 举例说明 算法实现 参考文献 前言 在并发系统中&#xff0c;同步与互斥是实现资源共享的关键Lamport面包店算法作为一种经典的解决并发问题的算法&#xff0c;它的实现原…

opencalib中lidar2camera安装记录

目录 一、opencalib安装 二、lidar2camera的安装 三、测试运行 四、出现过的问题 一、opencalib安装 代码地址&#xff1a;https://github.com/PJLab-ADG/SensorsCalibration/blob/master/README.md # pull docker image sudo docker pull scllovewkf/opencalib:v1 # Aft…

出海路上离不开的Email营销,教你这样来优化!

随着互联网的不断发展&#xff0c;Email已经成为人们工作和生活中不可或缺的一部分。尤其是对于我们这些跨境企业而言&#xff0c;发送Email是一个促进销售和维护客户关系的良好渠道。而且邮件的价格也是比较低廉的&#xff0c;很适合用于日常推广营销&#xff0c;所以人手几个…

【Linux】nginx基础篇 -- 介绍及yum安装nginx

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

光影之梦2:动画渲染前后对比,揭示视觉艺术的惊人转变!

动画渲染是影视艺术中不可或缺的一环&#xff0c;它赋予了角色和场景鲜活的生命。渲染过程中的光影、色彩、材质等元素&#xff0c;像是画家的调色板&#xff0c;将平淡无奇的线条和形状转化为充满韵味与情感的画面。动画角色仿佛拥有了自己的灵魂&#xff0c;无论是一颦一笑&a…

Unity Inspector编辑器扩展,枚举显示中文,枚举值自定义显示内容

记录&#xff01;Unity Inspector面板编辑器扩展&#xff0c;枚举显示中文&#xff0c;枚举值自定义显示内容&#xff0c;显示部分选项。效果如下&#xff1a; 枚举类代码&#xff1a; using System.Collections; using System.Collections.Generic; using UnityEngine;public…

9 线程池

目录 1 线程池各参数 1.1 corePoolSize 1.2 maximunPoolSize 1.3 keepAliveTime 1.4 workQueue 1.5 RejectedExecutionHandler 2 线程池工作机制 2.1 流程 2.2 提交任务 3 相关问题 3.1 线程池核心线程数、最大线程数设置 3.2 ApiPost压测 3.3 为什么要用阻塞队列…

初识Java篇

1.介绍Java语言 1.1Java是什么 Java是一种优秀的程序设计语言&#xff0c;它具有令人赏心悦目的语法和易于理解的语义。 不仅如此&#xff0c;Java还是一个有一系列计算机软件和规范形成的技术体系&#xff0c;这个技术体系提供了完整的用于软件开发和跨平台部署的支持环境&am…

小知识(5) el-table行样式失效问题

一、实现效果 子级呈现不同颜色去区分 二、最初代码 tips: 我这里使用的vue3 elementplus <el-table :row-class-name"tableRowClassName" >... </el-table>function tableRowClassName({ row, rowIndex }) {if (row.children.length 0) {return …

基于ElasticSearch+Vue实现简易搜索

基于ElasticSearchVue实现简易搜索 一、模拟数据 产品名称描述价格库存数量品牌名称智能手表智能手表&#xff0c;具有健康跟踪和通知功能。199.991000TechWatch4K智能电视4K分辨率智能电视&#xff0c;提供出色的画质。699.99500VisionTech无线耳机降噪无线耳机&#xff0c;…

html iframe 框架有哪些优缺点?

目录 前言&#xff1a; 用法&#xff1a; 理解&#xff1a; 优点&#xff1a; 嵌套外部内容&#xff1a; 独立性&#xff1a; 分离安全性&#xff1a; 跨平台兼容性&#xff1a; 方便维护&#xff1a; 缺点&#xff1a; 性能开销&#xff1a; 用户体验问题&#xf…

【网安大模型专题10.19】※论文5:ChatGPT+漏洞定位+补丁生成+补丁验证+APR方法+ChatRepair+不同修复场景+修复效果(韦恩图展示)

Keep the Conversation Going: Fixing 162 out of 337 bugs for $0.42 each using ChatGPT 写在最前面背景介绍自动程序修复流程Process of APR (automated program repair)1、漏洞程序2、漏洞定位模块3、补丁生成4、补丁验证 &#xff08;可以学习的PPT设计&#xff09;经典的…

独家揭秘微信视频号下载提取器,使用方法!

1&#xff1a;微信视频号下载提取器&#xff0c;需要先确认自己手机电脑版本是否支持视频号的观看和浏览 2:需要下载视频号的作品发给视频下载小助手&#xff0c;聊天窗口 3&#xff1a;打开小助手解析视频号视频链接&#xff0c;保存到手机相册或者电脑上 注意视频号电脑版…

适用于 Linux 和 Unix 的特权访问管理

凭据、SSH 密钥、服务帐户、数字签名、文件系统等内容构成了Linux 环境的关键部分&#xff0c;虽然大多数PAM供应商为基于Windows的环境提供无缝的特权访问管理&#xff0c;但它们的通用性不足以为Linux&#xff0c;Unix和*nix环境扩展相同的功能和功能。 Linux 中的root权限是…

wf-docker集群搭建(未完结)

系列文章目录 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 系列文章目录前言一、redis集群二、mysql集群三、nacos集群1. 环境要求2. 拉取镜像2.1. 拉取镜像方式配置集群2.2. 自定义nacos镜像配置集群 3 自定义…

基于PHP的图像分享社交平台

有需要请加文章底部Q哦 可远程调试 基于PHP的图像分享社交平台 一 介绍 此图像分享社交平台基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。平台角色分为用户和管理员。用户可注册登录&#xff0c;发布图像&#xff0c;修改个人信息&#xff0c;评论图像…

分享一下门店服务预约系统怎么做

随着科技的不断发展&#xff0c;越来越多的企业开始注重提高服务质量和效率。其中&#xff0c;门店服务预约系统成为了许多企业的选择。本文将探讨门店服务预约系统的意义、设计思路、实现方法、系统测试以及拓展案例&#xff0c;并总结门店服务预约系统设计和实现的重要性。 一…

国腾GM8775C完全替代CS5518 MIPIDSI转2 PORT LVDS

集睿致远CS5518描述&#xff1a; CS5518是一款MIPI DSI输入、LVDS输出转换芯片。MIPI DSI 支持多达4个局域网&#xff0c;每条通道以最 大 1Gbps 的速度运行。LVDS支持18位或24位像素&#xff0c;25Mhz至154Mhz&#xff0c;采用VESA或JEIDA格 式。它只能使用单个1.8v电源&am…

更改idea的JDK版本

有时候我们需要更改 idea 的 JDK 版本&#xff0c;这里告诉大家更改的方法&#xff0c;非常简单快捷&#xff0c;而且也不需要去找 JDK 的资源 1.在 idea 的左上角找到 File 选择 Peoject Structure 2.在页面左上角找到 Project &#xff0c;点击 SDK 的框&#xff0c;选择 A…

RISC-V架构——中断委托和中断注入

1、中断委托 1.1、中断委托的作用 &#xff08;1&#xff09;默认情况下&#xff0c;所有的陷入&#xff08;中断和异常&#xff09;都是在M模式下处理&#xff0c;然后再返回到发生陷入前的模式&#xff1b; &#xff08;2&#xff09;所有陷入都在M模式处理会涉及到模式切换…