动态规划(五)

2023-10-26

01背包问题 ( 01 Knapsack problem)

有10件货物要从甲地运送到乙地,每件货物的重量(单位:吨)和利润(单位:元)如下表所示:
在这里插入图片描述
由于只有一辆最大载重为30t的货车能用来运送货物,所以只能选择部分货物配送,要求确定运送哪些货物,使得运送这些货物的总利润最大。

1.1 原问题和子问题

原问题: 在满足重量约束的条件下,将这m件物品选择性的放入容量为W的背包中所能获得的最大利润.

子问题: 在满足重量约束的条件下,将前i (i <=m) 件物品选择性的放入容量为 (j<=W) 的背包中所能获得的最大利润.

其实这个问题我们可以采用自上而下的迭代,创建一个长为容量,宽为数量的二维矩阵,从第一行开始,第一行代表第一个物品,从左到右重量够的取最优解,然后开始第二行,即第二个物品,此时最优解涉及到第一个,可参考上一行的最优解,同第二个物品比较,得出两个物品的最优解…以此类推

1.2 寻找物品编号

我们现在来看一个例子
在这里插入图片描述

由于我们创建的那个表格是 物品和容量,所以先选出最后一列中取出最大的,然后回到上面的表,减去对应的物品编号,得出上一个物品,得出剩余的背包空间,以此类推,很像礼物问题的求出礼物编号
在这里插入图片描述

python 解法

import numpy as np
class solution():
    def __init__(self):
        self.profile= [11,12,10,26,14,16]
        self.weight = [3, 2 ,2, 5, 1, 3]
        self.W=10

    def total(self):
        ind=0
        num = len(self.profile)
        DP = np.zeros((num,self.W))
        #第一行
        if self.weight[0] < self.W :
            DP[0,(self.weight[0]-1):(self.W)]=self.profile[0]
        #第一列
        for i in range(1,num):
            for each in self.weight[0:i]:
                if each ==1:
                    IND=self.weight.index(1)
                    DP[i-1:num,0]=self.profile[IND]
                    ind=1
                    break
                
                if ind==0:
                    DP[i,0]=0

        for i in range(1,num):
            for j in range(1,self.W):
                if self.weight[i] > j+1:
                    DP[i,j]= DP[i-1,j]
                
                elif self.weight[i] == j+1:
                    DP[i,j]=max(DP[i-1,j],self.profile[i])

                else:
                    DP[i,j]=max(DP[i-1,j],self.profile[i]+DP[i-1,j-self.weight[i]])
        return DP
    
    def Object(self,DP):
        if len(DP)>0:
            Object_num=[]
            num = len(self.profile)
            
            ww=self.W
            tmp=list(DP[0:num,self.W-1])

            while 1:
                ind=tmp.index(max(tmp))
                ww=ww-self.weight[ind]
                Object_num.append(ind+1)
                if ((ind>1) ==True) and ((ww>0) ==True):
                    tmp=list(DP[0:ind,ww-1])
                else:
                    break
            result=Object_num.sort() 
        else:
            return -1
        return result
backpack=solution()
DP=backpack.total()
print(DP)
Object_num=backpack.Object(DP)
print(Object_num)

matlab 解法

p = [540,200,180,350,60,150,280,450,320,120]; %利润
w = [6   ,3,  4  ,5,  1, 2,  3,  5,  4,  2];  %重量
W = 30;                                       %容量
f = knapsack01problem1(p,w,W)

function [f, IND] = knapsack01problem2(p,w,W)
    % 输入: p:物品的利润  w:物品的重量  W:背包的容量
    % 为了编程方便,假设W是大于等于2的正整数;w中每个元素都是大于等于1的正整数
    m = length(p);  % 物品个数
    FF = zeros(m,W);  % 初始化DP数组
    % FF(i,j):前i件物品选择性的放入容量为j的背包中所能获得的最大利润
    if w(1) <= W  % 初始化第一行
        FF(1,w(1):end) = p(1);
    end
    for i = 2:m  % 初始化第一列
        FF(i,1) = max([p(w(1:i) == 1),0]);
    end
    % i,j>1的情况
    for i = 2:m
        for j = 2:W
            if w(i) > j  % 第i件物品的重量w(i)比背包的容量j还要大
                FF(i,j) = FF(i-1,j) ;
            elseif w(i) == j  % 第i件物品的重量w(i)等于背包的容量j
                FF(i,j) = max(FF(i-1,j), p(i));  % 不放进去和放进去取较大的值
            else  % 第i件物品的重量w(i)小于背包的容量j
               FF(i,j) = max(FF(i-1,j), p(i)+FF(i-1,j-w(i)));  % 不放进去和放进去取较大的值
            end
        end
    end
    f = FF(m,W);
    IND = [];  % 选择的物品编号IND初始化为空
    if f > 0   % 只要有利润,就可以利用FF来计算选择的物品编号IND
        ww = W;  % 初始化背包的剩余容量为整个背包的容量W
        tmp = FF(:,ww);  % 取出最后一列
        while 1  % 不断循环下去,后面通过条件判断来退出循环
            ind = find(tmp == max(tmp),1) ;  % 找到装入背包的那个物品
            ww = ww - w(ind);  % 更新背包的剩余容量
            IND = [IND,ind];  % 更新IND里面的元素
            if ind > 1 && ww>0  % 只要不是第一个物品或者背包容量为空
                tmp = FF(1:ind-1,ww);  % 重新取出剩余容量的那一列(只保留前面的物品)
            else
                break   % 跳出循环
            end
        end
        IND = sort(IND);  % 排序下,输出好看点
    end
end

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

动态规划(五) 的相关文章

  • 存储为 np.arrays 的不同数据集的分组堆积条形图

    我正在研究一个平衡问题 我想比较一些数据 我想通过创建不同年份的堆叠条形图来做到这一点 每年 我想要两个不同数据集的堆叠条形图 我正在尝试创建一种 分组堆积条形图 我设法创建了我想要比较的 2 个堆叠条形图 但它们仍然位于两个不同的图中 我
  • Python Numpy TypeError:输入类型不支持 ufunc 'isfinite'

    这是我的代码 def topK dataMat sensitivity meanVals np mean dataMat axis 0 meanRemoved dataMat meanVals covMat np cov meanRemov
  • 将 python scikit learn 模型导出到 pmml

    我想将 python scikit learn 模型导出到 PMML 中 什么 python 包最适合 我读到Augustus https github com opendatagroup augustus 但我找不到任何使用 scikit
  • python列表理解和extend() [重复]

    这个问题在这里已经有答案了 深入学习 Python 2 7 1 但未能理解这一点 几个小时 gt gt gt a 1 2 gt gt gt b 3 4 gt gt gt gt gt gt a extend b 0 gt gt gt a 1
  • 不要在异常堆栈中显示 Python raise-line

    当我在 Python 库中引发自己的异常时 异常堆栈将引发行本身显示为堆栈的最后一项 这显然不是一个错误 在概念上是正确的 但是当您在外部使用代码 例如作为模块 时 它会将重点放在对调试无用的东西上 有没有办法避免这种情况并强制 Pytho
  • 在 python 中返回 self [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一个代表对象的类 我有很多方法可以修改这个对象状态 没有明显的返回或显然没有任何返回 在 C 中 我会将所有这些方法声明为void
  • Python 3:如何更改GDAL中的图像数据?

    我有一个 GeoTIFF 图像 其中包含颜色表和带有 8 位表键的单个栅格带 并且使用 LZW 压缩 我加载该图像gdal Open https gdal org python osgeo gdal module html 我还有一个包含
  • PyKCS11 不可哈希列表

    我的 python 脚本旨在获取特定 so 库中插槽 令牌的详细信息 输出如下所示 Library manufacturerID Safenet Inc Available Slots 4 Slot no 0 slotDescription
  • 如何从 python 脚本更改 python 文件中的变量值

    我目前有一个 python 文件 其中包含一堆带有值的全局变量 我想从一个单独的 python 脚本永久更改这些值 我尝试过 setattr 等 但似乎不起作用 有没有办法做到这一点 简短的回答是 不 不值得这么麻烦 听起来您正在尝试创建一
  • 如何在 PyCharm 中启用 flake8 的自动代码格式化

    我使用 Tox 运行单元测试 并使用 flake8 命令检查代码格式错误 每次我在 PyCharm 中编码时 我都会运行 tox 然后意识到我有一堆烦人的格式错误 我必须返回并手动修复 我希望 PyCharm 自动格式化代码 根据 flak
  • 如何使用增量值向 Pyspark 中的 DataFrame 添加列?

    我有一个名为 df 的 DataFrame 如下所示 Atr1 Atr2 Atr3 A A A B A A C A A 我想向其中添加一个具有增量值的新列并获取以下更新的 DataFrame Atr1 Atr2 Atr3
  • 结束一天(日期时间)的最优雅的方式是什么?

    我目前正在编写一些报告代码 允许用户选择指定日期范围 它的工作方式 简化 是 用户 可选 指定年份 用户 可选 指定月份 用户 可选 指定一天 这是一个代码片段 以及描述我想要的内容的注释like to do from datetime i
  • 传递宏作为参数 jinja dbt

    Today date milliseconds 是我在项目中的宏 如何将此宏重定向为参数 以便默认情况下我可以在 yml 中编写另一个宏 test valid date model column name exclude condition
  • Kivy:滚动缩放

    有没有办法在桌面 kivy 应用程序上放大图像 例如使用鼠标滚轮缩放 这里似乎讨论过 https github com kivy kivy issues 3563 https github com kivy kivy issues 3563
  • 尝试输入字符串时出现名称错误[重复]

    这个问题在这里已经有答案了 import pickle import os import time class Person def init self number address self number number self addr
  • python字符串包含双引号字符

    我的输入字符串由字符组成 包括双引号和单引号 和 B SS JU PQ AD DDSFD ABD E J 但是 当我从文本文件打开上述输入并打印它时 第三行中的双引号 被打印为 xe2 x80 x9d 我的目标是进行简单的字符计数 B 2
  • Snakemake根据字典输入和输出

    我正在尝试重命名 Snakemake 管道中的一些文件 假设我有三个文件 FileA txt FileB txt FileC txt 我希望根据字典重新命名它们dict A 0 B 1 C 2 to get RenamedFile0 txt
  • launchd执行python脚本,但导入失败

    我使用 appscript 编写了一个 python 脚本来跟踪我当前活动的窗口 我通过 launchd 运行它 但是当我这样做时 它无法导入 appscript 我已经在 launchd 的 plist 中设置了 PYTHONPATH 但
  • Python list.extend() 是保序的吗?

    我想知道扩展函数是否保留两个列表中的顺序 gt gt list 1 2 3 gt gt list extend 4 5 gt gt list 1 2 3 4 5 扩展总是这样工作吗 Yes list extend just extends给
  • 预提交钩子 git 错误

    我正在尝试在 python 中执行预提交 git hook 以检查文件的行长度是否小于 80 个字符 但是我收到没有此类文件 目录的错误 我在 fedora 上并设置了 usr bin python help 将不胜感激 usr bin e

随机推荐

  • Protobuf C++ 版入门Demo

    Protobuf C 版入门Demo 前言 有关其编译和安装请查看 Protobuf C 版编译安装和简单使用 之前已经进行了编译安装 并且成功将已知的proto文件转化为cc和h 本文简单探讨如何使用Protobuf进行数据写入和读取 也
  • 使用three.js在Vue中创建3D图

    使用three js创建3D图 1 电梯 注意 只为自己做笔记用的 全部是收藏的博客地址当电梯用 1 电梯 1 展示 https wow techbrood com fiddle 34388 闪光球 https blog csdn net
  • 字典树(介绍+实现+例题)

    字典树 介绍 字典树也叫前缀树 Trie树等 字典树是一颗非典型的多叉树模型 字典树的结点包含有一个长度为26的指针数组 分别对应26个字母 指向当前字母对应的下一个字母 字典树充分利用了字符串的公共前缀 包含三个单词 sea sells
  • 【华为OD统一考试B卷

    在线OJ 已购买本专栏用户 请私信博主开通账号 在线刷题 运行出现 Runtime Error 0Aborted 请忽略 华为OD统一考试A卷 B卷 新题库说明 2023年5月份 华为官方已经将的 2022 0223Q 1 2 3 4 统一
  • 多线程如何在 C 中实现?

    多线程 英语 multithreading 是指从软件或者硬件上实现多个线程并发执行的技术 具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程 进而提升整体处理性能 具有这种能力的系统包括对称多处理机 多核心处理器以及芯片级
  • java内存马查杀工具

    java memshell scanner 扫描java内存马
  • 模版之AnyType

    title 模版之AnyType date 2023 02 19 21 49 53 permalink pages 54a0bf categories 通用领域 编程语言 C tags C 元编程 author name zhengzhib
  • Java里NonNull和NotNull

    https blog csdn net yangyangrenren article details 121180269 lombok NonNull 这个 annotation 是 lombok 提供的 根据官方的解释可以看出它是用来辅助
  • 华为OD机试 - 组成最大数(Java)

    题目描述 小组中每位都有一张卡片 卡片上是6位内的正整数 将卡片连起来可以组成多种数字 计算组成的最大数字 输入描述 号分割的多个正整数字符串 不需要考虑非数字异常情况 小组最多25个人 输出描述 最大的数字字符串 用例 输入 22 221
  • Pycharm 交互式Console BUG问题解决 - OSError: [Errno 22] Invalid argument: ‘D:\pyCHram\<input>‘

    引言 Pycharm python console是一个很好用的交互式编程栏 但是在跑一些深度学习模型的时候 偶尔会发生类似于这种错误的报错 导致无法在交互式的Python console模式下运行测试代码 Pycharm 问题解决 OSE
  • 攻防世界NewsCenter思路

    打开环境后发现是这样一个页面 考虑到xss或者sql注入 尝试了alert无果 便试试sql注入 随便输入aaa后使用burp抓包 将这些保存在1 txt里 用sqlmap抓包 命令 sqlmap py r 1 txt dbs 这里看到一个
  • U-Boot相关命令开发板烧写问题及解决方案

    前言 最近在学习u boot命令在开发板的烧写 在进行该实验的过程中 出现了很多问题和错误 在这里我根据自己的开发历程 将我出现的几大问题进行了汇总 并附有相关解决办法 这些解决方案都经过我亲自验证有效 希望能让大家在开发过程中有所启发 问
  • C++实现复化梯形公式求积分算法

    1 算法原理简介 步1 将积分区间2n等分 步2 调用复化梯形公式 2 应用实例 取 n 10 利用复化梯形公式计算积分 3 程序代码 include
  • BLDC无刷直流电机驱动电路-硬石电子

    1 BLDC无刷直流电机驱动电路 因为BLDC是三相完全一样的驱动电路 下图为其中一相电路图 其他两相完全一样 主要元器件 高速光耦 TLP715 MOS管驱动IC IR2110S MOS IRF540NS D7和C13为自举电路 2 霍尔
  • ubuntu18.04安装之后没有网络,不显示网络图标

    新安装的ubuntu18 04 06安装完成后插着网线 但是没有有线网 桌面上不显示网络图标 原因是因为ubuntu系统安装时自带的网卡驱动不兼容导致的 下面来讲解解决方法 首先 先试用手机连接线 将手机连接到电脑usb口 使用手机上的US
  • matlab中hash和map的用法总结

    若要在matlab中使用hash 有两种方式 1 采用matlab官方给出的结构类型map containers Map http cn mathworks com help matlab map containers html 2 调用J
  • 到底要不要孩子学习机器人编程

    人工智能发展迅猛 很多技术已经成熟应用到我们生活场景中 如果再不从小让孩子学习机器人编程教育 掌握更多编程语言 那未来就out啦 格物斯坦小坦克可以告诉你关于机器人编程要不要学的答案 教育部也将启动中小学生信息素养测评 并推动在中小学阶段设
  • uni-app利用chooseImage方法封装一个图片选择组件

    效果如图 可以预览 长按可删除 可以设置最多上传数量 这里封装的组件有个MaxNumber number类型 用的时候在父组件传就行了 这里默认给的8 废话不多说直接上代码 封装好了之后我们用的时候只需要引入直接用就行
  • 从etcd看Raft协议

    首先 什么是etcd 看官方的定义 A highly available key value store for shared configuration and service discovery 翻译过来就是 用于配置共享和服务发现的K
  • 动态规划(五)

    01背包问题 01 Knapsack problem 有10件货物要从甲地运送到乙地 每件货物的重量 单位 吨 和利润 单位 元 如下表所示 由于只有一辆最大载重为30t的货车能用来运送货物 所以只能选择部分货物配送 要求确定运送哪些货物