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

news2024/9/20 20:50:04

文章目录

    • 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.coloradmin.cn/o/1132769.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

命令行输入sns.countplot(data[‘marital‘])报错

代码sns.countplot(data[marital])是用于绘制柱状图来显示分类变量的频数分布。但是&#xff0c;根据警告信息&#xff0c;从Seaborn 0.12版本开始&#xff0c;只有一个有效的位置参数data&#xff0c;其他参数必须作为关键字参数传递。因此&#xff0c;你需要将参数data[marit…

【idea】使用教程:idea 打开项目、配置、项目打包详细教程

目录 一、配套软件安装 二、打开已有项目 三、配置 jdk 四、项目打包 五、服务器首次创建目录 &#xff08;1&#xff09;后端代码目录 &#xff08;2&#xff09;前端代码目录 &#xff08;3&#xff09; 打包后的代码包上传到服务器上 一、配套软件安装 【idea】wi…

current file is not included in a workspace moduleg 存在多个 main函数的 Go项目 无法成功导包

报错缘由 学习 hystria, 尝试自测案例,使用了 go get “github.com/afex/hystrix-go/hystrix” 进行导入包&#xff0c; 导入成功后&#xff0c;在代码里利用 import 导入&#xff0c;但遇到了以下报错 could not import github.com/afex/hystrix-go/hystrix (current file i…

WorkPlus打造安全专属的移动数字化航空母舰,助力企业全面掌控业务和生态

在快速发展的商业环境中&#xff0c;企业对于安全和全面掌控业务和生态的需求日益增长。WorkPlus作为一款安全专属的移动数字化航空母舰&#xff0c;为企业提供了独特的解决方案&#xff0c;助力企业全面掌控业务和生态&#xff0c;实现安全性和效率的最佳平衡。 WorkPlus提供…

游戏数据分析对于运营游戏平台的重要性

游戏数据分析对于运营游戏平台具有至关重要的意义&#xff0c;它可以提供深入的见解&#xff0c;帮助了解玩家行为、偏好和互动&#xff0c;从而优化游戏体验&#xff0c;提高玩家参与度和留存率。 首先&#xff0c;通过游戏数据分析&#xff0c;运营者可以了解玩家在游戏中的表…

山西电力市场日前价格预测【2023-10-26】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-10-26&#xff09;山西电力市场全天平均日前电价为343.86元/MWh。其中&#xff0c;最高日前电价为515.42元/MWh&#xff0c;预计出现在18: 15。最低日前电价为131.00元/MWh&#xff0c;预计…

centos7安装minio

MINIO官网地址&#xff1a;MinIO | 高性能分布式存储&#xff0c;私有云存储 可以在官网下在包 1.安装软件最好设置在 /usr/local路径下 cd /usr/local mkdir minio 2.在新创建的minio路径下执行 wget https://dl.minio.org.cn/server/minio/release/linux-amd64/minio 默…

废柴勇士(据说没有人能坚持37秒)

欢迎来到程序小院 废柴勇士 玩法&#xff1a;点击屏幕下方左右按键击杀怪物&#xff0c;怪物会在左右方向同时来袭&#xff0c;快速点击按钮进行击杀怪物&#xff0c;看您能够坚持多少秒&#xff0c; 据说还没有能够坚持37秒&#xff0c;快去击杀怪物挑战吧^^。开始游戏https:…

宏集案例 | Panarama SCADA平台在风电场测量的应用,实现风电场的高效管理!

文章来源&#xff1a;宏集工业物联网 阅读原文&#xff1a;https://mp.weixin.qq.com/s/MLYhBWiWx7qQSApx_3xhmA 宏集Panorama SCADA平台在风电场测量的应用 宏集方案 01应用背景 随着煤碳、石油等能源的逐渐枯竭&#xff0c;人类越来越重视可再生能源的利用。风能作为一种…

【电路笔记】-平均电压和均方根电压(RMS Voltage)

平均电压和均方根电压&#xff08;RMS Voltage&#xff09; 文章目录 平均电压和均方根电压&#xff08;RMS Voltage&#xff09;1、概述2、平均电压3、均方根电压&#xff08;RMS Voltage&#xff09;4、总结 1、概述 在 DC 状态下&#xff0c;只能对电压值进行一种定义&…

javascript原生态xhr上传多个图片,可预览和修改上传图片为固定尺寸比例,防恶意代码,加后端php处理图片

//前端上传文件 <!DOCTYPE html> <html xmlns"http://www.w3.org/1999/xhtml" lang"UTF-8"></html> <html><head><meta http-equiv"Content-Type" content"text/html;charsetUTF-8;"/><title…

微信小程序通过获取键盘高度解决键盘弹出挡住输入框问题

我在这里写了个输入名称的头 在电脑上看着这输入效果还是挺优秀的 但当真的运行在手机上时 就会发现 这键盘一弹出来 就挡住我们的输入框了 这里 我们可以这样实现 在data中定义一个数值类型 叫 focusHeight 然后 给我们弹层 加上一个固定定位 然后 通过 focusHeight来控制…

【MySQL】用户与权限管理

文章目录 一、用户管理1、用户信息表2、创建用户3、删除用户4、修改用户密码 二、权限管理1、MySQL 权限2、给用户授权3、回收用户权限 一、用户管理 之前为了方便&#xff0c;我们学习 MySQL 时统一使用的都是 root 账号进行登录&#xff0c;但在实际的开发场景中必然是需要进…

基于SpringBoot的水果销售网站

基于SpringBootVue的水果销售网站系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven角色&#xff1a;管理员、商家、用户 系统展示 主页 水果详情 可直接购买&#xff0c;…

【Overload游戏引擎细节分析】standard材质Shader

提示&#xff1a;Shader属于GPU编程&#xff0c;难写难调试&#xff0c;阅读本文需有一定的OpenGL基础&#xff0c;可以写简单的Shader&#xff0c;不适合不会OpenGL的朋友 一、Blinn-Phong光照模型 Blinn-Phong光照模型&#xff0c;又称为Blinn-phong反射模型&#xff08;Bli…

鸡尾酒学习——长岛冰茶

长岛冰茶 1、材料&#xff1a;冰块&#xff08;或者雪莲&#xff09;、白朗姆、伏特加、龙舌兰、金酒、柠檬、君度或者白兰地、可乐&#xff1b; 2、口感&#xff1a;酸甜苦口味&#xff0c;酒的苦涩较为明显&#xff08;怀疑是自己放了过多的柠檬汁导致苦涩感明显&#xff09…

CrossOver 23.6 让Mac可以运行Windows程序的工具

在当今数字化时代&#xff0c;虚拟机技术被广泛应用于软件开发、系统测试、网络安全等领域。虚拟机提供了一个隔离的虚拟环境&#xff0c;使得我们能够在一台物理计算机上同时运行多个操作系统和应用程序。下面我们就来看虚拟机软件怎么安装&#xff0c;虚拟机怎么使用吧&#…

强制指定变量地址与局部优化

目录 一、强制编译器将变量分配到指定地址1. 编译器AC5.0与AC6.0有区别 二、 Keil/IAR局部优化1 IAR2.Keil AC5.03.Keil AC6.0 三 arm-none-eabi-gcc 下指定固定地址 一、强制编译器将变量分配到指定地址 1. 编译器AC5.0与AC6.0有区别 二、 Keil/IAR局部优化 1 IAR #pragma …

RTL SDR的PYTHON开发环境搭建

不得不说RTL SDR真是神器&#xff0c;直接把SDR的入门门槛拉低到了几十块钱。对于RTL SDR的学习开发&#xff0c;有大佬写的《Software_Defined_Radio_using_MATLAB_Simulink_and_the_RTL-SDR》&#xff0c;另外&#xff0c;除了MATLAB&#xff0c;近些年爆火的PYTHON当然也是可…

电厂数据可视化三维大屏展示平台加强企业安全防范

园区可视化大屏是一种新型的信息化手段&#xff0c;能够将园区内各项数据信息以图像的形式直观呈现在大屏幕上&#xff0c;便于管理员和员工进行实时监控、分析和决策。本文将从以下几个方面介绍园区可视化大屏的作用和应用。 VR数字孪生园区系统是通过将实际园区的各种数据和信…