【动态规划算法】【Python实现】0-1背包

文章目录

问题描述

  • 给定 n n n种物品和一背包,物品 i i i的重量是 w i w_{i} wi,其价值为 v i v_{i} vi,背包的容量为 c c c
  • 如何选择装入背包中的物品,使得装入背包中物品的总价值最大
形式化描述
  • 给定 c > 0 c > 0 c>0 w i > 0 w_{i} > 0 wi>0 v i > 0 ( 1 ≤ i ≤ n ) v_{i} > 0 (1 \leq i \leq n) vi>0(1in),找出一个 n n n 0 − 1 0-1 01向量 ( x 1 , x 2 , ⋯   , x n ) (x_{1} , x_{2} , \cdots , x_{n}) (x1,x2,,xn) x i ∈ {   0 , 1   } ( 1 ≤ i ≤ n ) x_{i} \in \set{0 , 1} (1 \leq i \leq n) xi{0,1}(1in),使得 ∑ i = 1 n w i x i ≤ c \displaystyle\sum\limits_{i = 1}^{n}{w_{i} x_{i}} \leq c i=1nwixic,而且 ∑ i = 1 n v i x i \displaystyle\sum\limits_{i = 1}^{n}{v_{i} x_{i}} i=1nvixi达到最大
  • 0 − 1 0-1 01背包问题是一个特殊的整数规划问题

max ⁡ ∑ i = 1 n v i x i { ∑ i = 1 n w i x i ≤ c x i ∈ {   0 , 1   } ( 1 ≤ i ≤ n ) \max\displaystyle\sum\limits_{i = 1}^{n}{v_{i} x_{i}} \kern{2em} \begin{cases} \displaystyle\sum\limits_{i = 1}^{n}{w_{i} x_{i} \leq c} \\ x_{i} \in \set{0 , 1} (1 \leq i \leq n) \end{cases} maxi=1nvixi i=1nwixicxi{0,1}(1in)


最优子结构性质

  • ( y 1 , y 2 , ⋯   , y n ) (y_{1} , y_{2} , \cdots , y_{n}) (y1,y2,,yn)是所给 0 − 1 0-1 01背包问题的一个最优解,则 ( y 2 , y 3 , ⋯   , y n ) (y_{2} , y_{3} , \cdots , y_{n}) (y2,y3,,yn)是下面相应子问题的一个最优解

max ⁡ ∑ i = 2 n v i x i { ∑ i = 2 n w i x i ≤ c − w 1 y 1 x i ∈ {   0 , 1   } ( 2 ≤ i ≤ n ) \max\displaystyle\sum\limits_{i = 2}^{n}{v_{i} x_{i}} \kern{2em} \begin{cases} \displaystyle\sum\limits_{i = 2}^{n}{w_{i} x_{i}} \leq c - w_{1} y_{1} \\ x_{i} \in \set{0 , 1} (2 \leq i \leq n) \end{cases} maxi=2nvixi i=2nwixicw1y1xi{0,1}(2in)

  • 否则,设 ( z 2 , z 3 , ⋯   , z n ) (z_{2} , z_{3} , \cdots , z_{n}) (z2,z3,,zn)是上述子问题的一个最优解,而 ( y 2 , y 3 , ⋯   , y n ) (y_{2} , y_{3} , \cdots , y_{n}) (y2,y3,,yn)不是它的最优解,由此可知, ∑ i = 2 n v i z i > ∑ i = 2 n v i y i \displaystyle\sum\limits_{i = 2}^{n}{v_{i} z_{i}} > \displaystyle\sum\limits_{i = 2}^{n}{v_{i} y_{i}} i=2nvizi>i=2nviyi,且 w 1 y 1 + ∑ i = 2 n w i z i ≤ c w_{1} y_{1} + \displaystyle\sum\limits_{i = 2}^{n}{w_{i} z_{i}} \leq c w1y1+i=2nwizic,因此 v 1 y 1 + ∑ i = 2 n v i z i > ∑ i = 1 n v i y i v_{1} y_{1} + \displaystyle\sum\limits_{i = 2}^{n}{v_{i} z_{i}} > \displaystyle\sum\limits_{i = 1}^{n}{v_{i} y_{i}} v1y1+i=2nvizi>i=1nviyi,说明 ( y 1 , z 2 , ⋯   , z n ) (y_{1} , z_{2} , \cdots , z_{n}) (y1,z2,,zn)是所给 0 − 1 0-1 01背包问题的一个更优解,从而 ( y 1 , y 2 , ⋯   , y n ) (y_{1} , y_{2} , \cdots , y_{n}) (y1,y2,,yn)不是所给 0 − 1 0-1 01背包问题的最优解,此为矛盾

递归关系

  • 设所给 0 − 1 0-1 01背包问题的子问题 max ⁡ ∑ k = i n v k x k { ∑ k = i n w k x k ≤ j x k ∈ {   0 , 1   } ( i ≤ k ≤ n ) \max\displaystyle\sum\limits_{k = i}^{n}{v_{k} x_{k}} \kern{2em} \begin{cases} \displaystyle\sum\limits_{k = i}^{n}{w_{k} x_{k} \leq j} \\ x_{k} \in \set{0 , 1} (i \leq k \leq n) \end{cases} maxk=invkxk k=inwkxkjxk{0,1}(ikn)的最优值为 m ( i , j ) m(i , j) m(i,j),即 m ( i , j ) m(i , j) m(i,j)是背包容量为 j j j,可选择物品为 i i i i + 1 i + 1 i+1 ⋯ \cdots n n n 0 − 1 0-1 01背包问题的最优值
m ( i , j ) m(i , j) m(i,j)递归方程

m ( i , j ) = { max ⁡ {   m ( i + 1 , j ) , m ( i + 1 , j − w i ) + v i   } , j ≥ w i m ( i + 1 , j ) , 0 ≤ j < w i m(i , j) = \begin{cases} \max\set{m(i + 1 , j) , m(i + 1 , j - w_{i}) + v_{i}} , & j \geq w_{i} \\ m(i + 1 , j) , & 0 \leq j < w_{i} \end{cases} m(i,j)={max{m(i+1,j),m(i+1,jwi)+vi},m(i+1,j),jwi0j<wi

m ( n , j ) = { v n , j ≥ w n 0 , 0 ≤ j < w n m(n , j) = \begin{cases} v_{n} , & j \geq w_{n} \\ 0 , & 0 \leq j < w_{n} \end{cases} m(n,j)={vn,0,jwn0j<wn


Python实现

def knapsack(weights, values, capacity):
    n = len(weights)

    # 创建一个二维数组用于保存子问题的解
    dp = [[0] * (capacity + 1) for _ in range(n + 1)]

    # 填充二维数组
    for i in range(1, n + 1):
        for j in range(1, capacity + 1):
            # 当前物品的重量大于背包容量, 无法放入背包
            if weights[i - 1] > j:
                dp[i][j] = dp[i - 1][j]
            # 考虑将当前物品放入背包和不放入背包两种情况, 选择价值最大的方案
            else:
                dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weights[i - 1]] + values[i - 1])

    # 构造最优解
    selected_items = []

    i, j = n, capacity
    while i > 0 and j > 0:
        # 当前物品被选中
        if dp[i][j] > dp[i - 1][j]:
            selected_items.append(i - 1)

            j -= weights[i - 1]

        i -= 1

    selected_items.reverse()

    return dp[n][capacity], selected_items


weights = [2, 3, 4, 5]
values = [3, 4, 5, 6]
capacity = 8

max_value, selected_items = knapsack(weights, values, capacity)

print(f'最大价值为: {max_value}')
print(f'选中的物品索引为: {selected_items}')

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构与算法(5)队列的基本操作

#include<stdio.h> #include<stdlib.h> #include<stdbool.h> typedef int ElemType; #define MaxSize 10//队列的定义 typedef struct SqQueue {ElemType data[MaxSize];int front, rear;//front为头指针&#xff0c;rear为尾指针。这里并不是真正的“指针”…

Java | Spring框架 | @Autowired与@Resource

在Spring框架中&#xff0c;依赖注入是一种核心概念&#xff0c;它允许开发者将对象的创建和对象之间的依赖关系的管理交给框架来处理。这样做的目的是为了提高代码的模块化和可测试性。 Spring提供了多种方式来实现依赖注入&#xff0c;其中最常用的方式是通过注解。在本文中…

mysql数据库---操作数据库跟表的命令总结

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 本文着重整理mysql管理库跟表的指令。 不涉及增删查改等指令 其实本篇主要是我做好笔记格式 用的时候直接复制粘贴的 所以排版大多是为了快速找功能来排的 方便大家快速找目标语法 数据库的简介 一个数据库系…

[Redis] 使用布隆过滤器和分布式锁实现用户注册

布隆过滤器&#xff08;Bloom Filter&#xff09;是一种数据结构&#xff0c;用于快速判断一个元素是否可能存在于一个集合中。它通过使用多个哈希函数和一个位数组来表示一个集合&#xff0c;当一个元素被加入到集合时&#xff0c;通过哈希函数计算出多个哈希值&#xff0c;并…

Hypack 2024 简体中文资源完整翻译汉化已经全部完成

Hypack 2024 简体中文资源完整翻译汉化已经全部完成 Hypack 2024&#xff0c;资源汉化共翻译11065条。毕竟涉及测绘、水文、疏浚等专业术语太多&#xff0c;翻译有很多理解不正确的地方&#xff0c;望各位专业人员指正。 压缩包内包含Hypack 2024、Hypack 2022、Hypack 2021、…

什么样的行业适合做私域?

私域营销适用于各种行业&#xff0c;但以下几个行业尤其适合进行私域营销&#xff1a; 1、零售行业&#xff1a;私域营销可以帮助零售企业建立与顾客的直接联系&#xff0c;提高顾客忠诚度和复购率。通过私域营销&#xff0c;零售企业可以进行个性化推荐、定制化服务&#xff…

JavaWeb--11MySQL(3)-- 多表设计

MySQL&#xff08;3&#xff09;-- 多表设计 1 一对多&#xff08;多对一&#xff09;2 一对一3 多对多 各个表结构之间也存在着各种联系&#xff0c;基本上分为三种&#xff1a; 一对多(多对一)多对多一对一 1 一对多&#xff08;多对一&#xff09; 一对多关系实现&#x…

【Java】IO流:字节流 字符流 缓冲流

接续上文&#xff0c;在这篇文章将继续介绍在Java中关于文件操作的一些内容【Java】文件操作 文章目录 一、“流”的概念1.“流”的分类1.1输入流和输出流1.2字节流和字符流 字节和字符的区别&#xff1f;为什么要有字符流&#xff1f;1.3节点流和处理流 字符流自带缓冲区&…

【Linux——Centos7安装RabbitMQ】 RabbitMQ无法连接

到这一步是基本已经装好了&#xff0c;现在是在开放端口&#xff0c;我这个报错是因为我的防火墙是处于关闭状态&#xff0c;所以在开放端口时会报防火墙为运行&#xff0c;把防火墙打开&#xff0c;在开放端口&#xff0c;就可以访问到了 重启防火墙&#xff1a; systemctl …

【无标题】基于GIS、Python机器学习技术的地质灾害风险评价、易发性分析与信息化建库及灾后重建中的实践技术

理解地质灾害形成机理与成灾模式&#xff1b;从空间数据处理、信息化指标空间数据库构建、致灾因子提取&#xff0c;空间分析、危险性评价与制图分析等方面掌握GIS在灾害危险性评价中的方法&#xff1b;运用地质灾害危险性评价原理和技术方法 原文链接&#xff1a;基于GIS、Py…

DeepSeek API文档:创建对话补全的指南

DeepSeek平台不仅提供了一个用户友好的聊天界面&#xff0c;还为开发者提供了强大的API接口&#xff0c;使他们能够创建和集成智能对话补全功能。以下是关于如何使用DeepSeek API创建对话补全的详细介绍。 DeepSeek API概述 DeepSeek的API允许开发者通过编程方式与DeepSeek的…

应用软件安全保证措施方案书

系统安全保证措施方案—word原件 软件全套资料进主页获取或者本文末个人名片直接获取。

【文章转载】ChatGPT 提示词十级技巧: 从新手到专家

学习了微博网友宝玉xp老师《ChatGPT 提示词十级技巧: 从新手到专家》 个人学习要点&#xff1a; 1、关于提示中避免使用否定句&#xff0c;播主说&#xff1a;“没有人能准确解释为什么&#xff0c;但大语言模型在你告诉它去做某事时&#xff0c;表现似乎比你让它不做某事时更…

识货小程序逆向

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;wx a15018601872&#xff0c;x30184483x…

Java进阶07集合(续)

Java进阶07 集合&#xff08;续&#xff09; 一、数据结构&#xff08;树&#xff09; 1、关于树 1.1 相关概念 节点&#xff1a;树中每个单独的分支 节点的度&#xff1a;每个节点的子节点数量 树高&#xff1a;树的总层数 根节点&#xff1a;最顶层节点 左子节点&…

6层板学习笔记2

说明:笔记基于6层全志H3消费电子0.65MM间距BGA 67、多层板的电源建议直接大面积铺铜,不建议走线,铺铜充分满足其载流能力 68、凡亿推荐表层1OZ的铜厚线宽20MIL能承载1A的电流,内层0.5OZ的铜厚线宽为40MIL能承载1A的电流,过孔直径20MIL(0.5MM)能承载1A左右的电流,实际设…

typescript的入门到吐槽:看了typescript,发现前端真的卷,

typescript TypeScript 是一种由微软开发的自由和开源的编程语言。它是 JavaScript 的一个超集&#xff0c;而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。 TypeScript 与 JavaScript 的区别 其实就是对JavaScript的封装&#xff0c;把一个弱类型语言封…

remmina无法连接远程桌面,Remmina无法连接远程桌面的原因与解决办法

在解决Remmina无法连接远程桌面的问题时&#xff0c;我们需要考虑多种可能的原因&#xff0c;并采取相应的解决办法。以下是一些常见的原因及其对应的解决方案&#xff1a; 1、网络问题 原因&#xff1a;不稳定的网络连接或中断可能导致无法建立远程桌面连接。 解决办法&#x…

MySQL数据库---增删查改汇总

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 本文着重整理MySQL数据库增删查改功能 主要是整理语法 争取做到要用什么语法 可以快速找到复制粘贴 增添语法 INSERT into tab(列名,列名,列名) values(内容,内容,内容); 插入一行数据 INSERT into tab(列名,…

Kubernetes最小单元Pod介绍及配置

1.1 Pod介绍 Pod是Kubernetes中的一个基本构建块&#xff0c;它是一个逻辑主机&#xff0c;用于托管一个或多个容器。 Pod中的容器共享网络和存储资源&#xff0c;并且通常作为一个单元一起调度和管理。 Pod为容器提供了一个共享的环境&#xff0c;使得容器之间可以方便地通信…