【算法】用动态规划求解背包问题

news2024/10/6 1:39:15

1.问题描述

有n种物品,每种物品的单件重量为w[i],价值为v[i]。现有一个容量为V的背包,如何选取物品放入背包,使得背包内物品的总价值最大。
下面是本题中我们使用的例子:
有三个物品,第一个物品的重量为3,价值为4;第二个物品的重量为4,价值为5;第三个物品的重量为5,价值为6。背包的总重量是10,求解背包能放下物品的最大价值。

2.算法描述

2.1 状态转移方程

该背包问题我们用动态规划的思想求解,构造一个二维数组表,以物品为纵坐标,以背包容量为横坐标,记录在不同背包容量下,当前物品摆放与否的最优解。
对第i件物品来说,他的最优解有两种情况:
1.不放第i件物品,那么 dp[ i ][ j ] = dp[ i - 1 ][ j ]
2.放第i件物品。如果选择放这一件物品,那么此时背包需要足够的剩余容量来放置这第i件物品,此时 dp[ i ][ j ] = dp[ i - 1 ][ j - w[i] ] + v[ i ]
我们可以得出此问题的状态转移方程
dp[i][j] = max{dp[ i - 1 ][ j - w[ i ] ] + v[ i ], dp[ i - 1 ][ j ]} 1<=i <=n, w[i] <= j <= V

此时我们的边界条件是:dp[ 0 ][ v ] = 0(0 <= v <= V)

递推求解

在上一步我们已经得到了状态转移方程,此时我们将该方程运用到构造出的二维表中,得到位置在i,j下的最优解,并记录下他的来源。
请添加图片描述

实验代码

import copy
if __name__ == "__main__": 
    weight = [3,4,5]
    value = [4,5,6]
    capacity = 10
    dp = []
    temp = []
    lastnode = []
    for v in range(capacity+1):
        temp.append(0)
    for u in range(len(weight) + 1):
        temp1 = copy.deepcopy(temp)
        temp2 = copy.deepcopy(temp)
        dp.append(temp1)
        lastnode.append(temp2)
    for i in range(1,len(weight)+1):
        for j in range(1,capacity+1):
            if j-weight[i-1] < 0:
                dp[i][j] = dp[i-1][j]
                lastnode[i][j] = 1 #1表示上一跳是dp[i-1][j]
            else:
                if dp[i-1][j-weight[i-1]]+value[i-1] > dp[i-1][j]:
                    dp[i][j] = dp[i-1][j-weight[i-1]]+value[i-1]
                    lastnode[i][j] = -1 #-1表示上一跳是dp[i-1][j-s[i]]
                else:
                    dp[i][j] = dp[i-1][j]
                    lastnode[i][j] = 1 #1表示上一跳是dp[i-1][j]
                
    print("dp:",dp)
    print(dp[-1][-1])
    u= len(weight)
    v= capacity 
    track = []
    for i in range(len(weight)):
      if lastnode[u][v] == -1:
          u = u-1
          v = v-weight[len(weight)-1-i]
          #print("u:",u,"v:",v)
          track.append(value[len(value)-1-i])
      else:
          u = u-1
          v = v
          #print("u:",u,"v:",v)
    track.reverse()
    print("当前背包中装的物品为:",track)
    print("当前背包的最大重量为:",sum(track))

4.实验结果

4.1实验结果

运行代码后,我们得到了下图所示的结果,与我们的推论相符,实验成功。
在这里插入图片描述

4.2 实验测试
用测试数据集测试五组数据的正确性:
1.
weight: [5, 6, 4, 3, 8, 4, 2]
value: [10, 1, 6, 9, 3, 4, 2]
capacity: 13
answer: 25
在这里插入图片描述

weight: [6, 1, 6, 1]
value: [2, 5, 6, 2]
capacity: 15
answer: 15
在这里插入图片描述
3.
weight: [9, 3]
value: [9, 6]
capacity: 19
answer: 15
在这里插入图片描述
4.
weight: [2, 1, 5, 4, 7, 4, 1, 7]
value: [4, 6, 7, 1, 1, 3, 2, 2]
capacity: 20
answer: 24
在这里插入图片描述
5.
weight: [8, 8, 9, 6, 10, 6]
value: [4, 2, 4, 10, 1, 1]
capacity: 16
answer: 14
在这里插入图片描述

5.优化策略

在状态转移方程中,计算dp[i][j]时总是只需要dp[i-1][j]左侧部分的数据。且当计算dp[i+1][]的部分时,dp[i-1]的数据就用不到了。因此,为了节省空间开销,我们可以选择使用一个一维数据存储。

6.参考和致谢

[1]胡凡,曾磊.算法笔记[M].机械工业出版社:北京,2016.7:390-392.
[2]【MIT课程】动态规划I-最短路径算法 https://www.bilibili.com/video/BV1Y441157H7
[3]漫画:什么是动态规划?(整合版) https://www.sohu.com/a/149075950_684445

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

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

相关文章

【附源码】Python计算机毕业设计图书销售系统设计

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

用友vs金蝶产品分析(云星空与YonSuite)

产品定位 用友与金蝶二者面对的客户群体是相同的&#xff1a;都是为成长型企业提供一体化服务&#xff0c;由于金蝶云星空发展较早&#xff0c;在部分产品功能上具备一定的先发优势&#xff1b;在产品的架构上&#xff0c;由于YS采用目前最先进的云原生和微服务架构&#xff0…

Bootstrap(一)

目录&#xff1a; &#xff08;1&#xff09;bootstrap容器 1.简单框架使用 2.流体容器 3.固定容器 4.栅格系统 &#xff08;1&#xff09;bootstrap容器 1.简单框架使用 bootstrap-3.3.7、bootstrap-3.3.7-dist 是原码文件&#xff0c;带dist是编译完的&#xff0c;里面…

5.C语言常见运算符及其优先级

运算符 用算术运算符将运算对象&#xff08;也称操作数&#xff09;连接起来的、符合C语言规则的式子&#xff0c;称为C算术表达式。运算对象包括常量、变量、函数等。 例如&#xff1a;a * b / c - 1.5 ‘a’ 运算符的分类 1.双目运算符&#xff1a;即参加运算的操作数有两…

SpringBoot--获取路径中的参数(x-www-form-urlencoded)--方法/实例

原文网址&#xff1a;SpringBoot--获取路径中的参数(x-www-form-urlencoded)--方法/实例_IT利刃出鞘的博客-CSDN博客 简介 本文用示例介绍SpringMVC如何获取路径中的参数。也就是&#xff1a; Content-Type为x-www-form-urlencoded。 代码 Controller BasicController.java…

在线考试系统

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

Prometheus邮件告警

一. 部署Alertmanager&#xff1a; 1. 解压Alertmanager压缩包&#xff1a; [rootnode5 ~]# tar xf alertmanager-0.24.0.linux-amd64.tar.gz -C /usr/local/ 2. 为解压后的文件做软连接&#xff1a; [rootnode5 ~]# ln -sv /usr/local/alertmanager-0.24.0.linux-amd64/ …

SSM整合(三)

redis之简单使用 1.准备工作 1.1 在resource资源文件夹下面创建redis.properties文件,并填写如下内容 #连接端口 redis.port6379 #连接地址 redis.host127.0.0.1 #超时时间&#xff1a;单位ms redis.timeout3000 #授权密码 redis.password #最大连接数&#xff1a;能够同时建…

GUI编程--PyQt5--QLineEdit

文章目录键盘文本输入框文本占位符密码显示与隐藏自动补全输入限制掩码字符光标移动设置文本区域常用编辑功能输入控件&#xff0c;用于捕获用户的信息键盘文本输入框 QLineEdit, 单行&#xff0c;纯文本输入框 # 实例化 文本输入框 le QLineEdit("默认值", windo…

Material Design之CoordinatorLayout 与AppbarLayout与CollapsingToolbarLayout

Material Design 之 CoordinatorLayout 第一次接触CoordinatorLayout 你可能有这些疑问&#xff0c;CoordinatorLayout 到底是个什么玩意儿呢&#xff1f;它到底能帮我们做什么&#xff1f;我们要了解它&#xff0c;肯定是先看官方文档了。文档的第一句话就非常醒目&#xff1a…

高职网络系统管理比赛实例

同一交换机不同端口配置不同vlan&#xff0c;实现同一交换机内不同业务部门隔离。 在路由器中配置斜面的内容 1 输入enableRuijie>enable 2 第一次使用该交换机时&#xff0c;需要设置密码&#xff0c;然后再次确认密码 Please Set the password:*** Please check the pass…

掌握这10个Pandas函数,助你彻底了解数据集

10个帮助你完全理解数据集的Pandas 函数 长按关注《Python学研大本营》&#xff0c;加入读者群&#xff0c;分享更多精彩 扫码关注《Python学研大本营》&#xff0c;加入读者群&#xff0c;分享更多精彩 Pandas是用于探索性数据分析 (EDA)的最佳 Python 模块。 许多初级数据科…

如何在liunx下实现一个简单的程序?

目录&#xff1a;安装nano写代码保存退出查看文件内容生成可执行程序控制台输出你的代码博后小知识&#xff08;gcc -g -o -c分别是什么意思&#xff1f;&#xff09;安装nano [rootVM-8-11-centos ~]# yum install -y nano 写代码 [rootVM-8-11-centos ~]# nano no_die.c 保存…

向量加权平均算法附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

【C++学习第八讲】简单变量(二)

目录&#xff1a;简单变量&#xff08;二&#xff09;一、无符号类型二、选择整型类型三、 char类型&#xff1a;字符和小整数一、无符号类型 前面介绍的4种整型都有一种不能存储负数值的无符号变体&#xff0c;其优点是可以增大变量能够存储的最大值。 例如&#xff0c;如果…

软件测试---

一 : 主要内容 二 : 什么是软件测试 在规定的条件下对程序进行操作&#xff0c;以发现程序错误&#xff0c;衡量软件质量&#xff0c;并对其是否能满足设计要求进行评估的过程.上面这是官话 . 在我们日常生活中 , 就有许多测试的行为 , 比如地铁站的金属检测仪 , 用于检测旅客…

深度学习——损失函数推导过程(三个方面诠释损失函数的由来意义)

三个维度诠释损失函数 我们在学习机器学习的过程中&#xff0c;通常利用损失函数来衡量模型所做出的预测离真实值之间的偏离程度。 损失函数大致分为3类方法 最小二乘法极大似然估计法交叉熵 1.最小二乘法 这个方法是最显而易懂的&#xff0c;假设x是真实值&#xff0c;y是…

【PyTorch】Neural Network 神经网络

文章目录四、Neural Network 神经网络1、Containers - Module2、Convolution Layers - functional.conv2d2.1 stride2.2 padding3、Convolution Layers - Conv2d3.1 in_channels out_channels4、Pooling layers - MaxPool2d4.1 ceil_mode4.2 TensorBoard5、Non-linear Activati…

Eclipse启动SpringBoot无法读取application.properties或者application.yml文件内容

原因 eclipse配置源代码excludes过滤掉了application.properties或application.yml造成的 解决 2.1 右键项目&#xff0c;选Build Path --> Configure Build Path 2.2 找到 Source --> resources --> Excluded&#xff0c;点击Edit 2.3 点击Edit 2.4 将**改成Non…

【Java八股文总结】之多线程

文章目录Java多线程一、线程1、什么是线程&#xff1f;什么是进程&#xff1f;二者的区别1、给线程起别名的3种方式2、this关键字3、守护线程和用户线程4、并发和并行的区别&#xff1f;5、线程间通信的方式2、synchronized关键字补充&#xff1a;snchronized底层实现原理3、vo…