动态规划之01背包问题及其优化(python实现)「建议收藏」

动态规划之01背包问题及其优化(python实现)「建议收藏」动态规划之01背包问题及其优化(python实现)**背包问题(**Knapsackproblem)是一种组合优化的NP完全问题。问题描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。问题的名称来源于如何选择最合适的物品放置于给定背包中。解决思路:动态规划,对每一件物品遍历背包容量,当背包可容纳值大于等于当前物品,与之前已放…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

动态规划之01背包问题及其优化(python实现)

**背包问题(**Knapsack problem)是一种组合优化的NP完全问题。
问题描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。问题的名称来源于如何选择最合适的物品放置于给定背包中。

解决思路:动态规划,对每一件物品遍历背包容量,当背包可容纳值大于等于当前物品,与之前已放进去的物品所得价值进行对比,考虑是否需要置换。

递归定义如下:
这里写图片描述

python实现算法如下:

def bag(n, c, w, v):
    """ 测试数据: n = 6 物品的数量, c = 10 书包能承受的重量, w = [2, 2, 3, 1, 5, 2] 每个物品的重量, v = [2, 3, 1, 5, 4, 3] 每个物品的价值 """
    # 置零,表示初始状态
    value = [[0 for j in range(c + 1)] for i in range(n + 1)]
    for i in range(1, n + 1):
        for j in range(1, c + 1):
            value[i][j] = value[i - 1][j]
            # 背包总容量够放当前物体,遍历前一个状态考虑是否置换
            if j >= w[i - 1] and value[i][j] < value[i - 1][j - w[i - 1]] + v[i - 1]:
                value[i][j] = value[i - 1][j - w[i - 1]] + v[i - 1]
    for x in value:
        print(x)
    return value

输入测试数据结果如下:最大价值为15
这里写图片描述

接下来,输出背包里所放的物品,只需从尾遍历物品,当value大于上一行同样位置的value时,表示放进该物品

代码如下:

def show(n, c, w, value):
    print('最大价值为:', value[n][c])
    x = [False for i in range(n)]
    j = c
    for i in range(n, 0, -1):
        if value[i][j] > value[i - 1][j]:
            x[i - 1] = True
            j -= w[i - 1]
    print('背包中所装物品为:')
    for i in range(n):
        if x[i]:
            print('第', i+1, '个,', end='')

输出结果:
这里写图片描述

以上时间复杂度为O(cn),已经不能再优化了。但空间复杂度O(cn)可以优化为O(c)。
思路:尾部迭代,每个状态表示上一次的最佳结果。
实现代码如下;

def bag1(n, c, w, v):
    values = [0 for i in range(c+1)]
    for i in range(1, n + 1):
        for j in range(c, 0, -1):
            # 背包总容量够放当前物体,遍历前一个状态考虑是否置换,这里的value[j]即为上一次最佳结果
            if j >= w[i-1]:
                values[j] = max(values[j-w[i-1]]+v[i-1], values[j])
    return values

完整代码:

#coding:utf-8

def bag(n, c, w, v):
    """ 测试数据: n = 6 物品的数量, c = 10 书包能承受的重量, w = [2, 2, 3, 1, 5, 2] 每个物品的重量, v = [2, 3, 1, 5, 4, 3] 每个物品的价值 """
    # 置零,表示初始状态
    value = [[0 for j in range(c + 1)] for i in range(n + 1)]
    for i in range(1, n + 1):
        for j in range(1, c + 1):
            value[i][j] = value[i - 1][j]
            # 背包总容量够放当前物体,遍历前一个状态考虑是否置换
            if j >= w[i - 1] and value[i][j] < value[i - 1][j - w[i - 1]] + v[i - 1]:
                value[i][j] = value[i - 1][j - w[i - 1]] + v[i - 1]
    for x in value:
        print(x)
    return value

def show(n, c, w, value):
    print('最大价值为:', value[n][c])
    x = [False for i in range(n)]
    j = c
    for i in range(n, 0, -1):
        if value[i][j] > value[i - 1][j]:
            x[i - 1] = True
            j -= w[i - 1]
    print('背包中所装物品为:')
    for i in range(n):
        if x[i]:
            print('第', i+1, '个,', end='')

def bag1(n, c, w, v):
    values = [0 for i in range(c+1)]
    for i in range(1, n + 1):
        for j in range(c, 0, -1):
            # 背包总容量够放当前物体,遍历前一个状态考虑是否置换
            if j >= w[i-1]:
                values[j] = max(values[j-w[i-1]]+v[i-1], values[j])
    return values


if __name__ == '__main__':
    n = 6
    c = 10
    w = [2, 2, 3, 1, 5, 2]
    v = [2, 3, 1, 5, 4, 3]
    value = bag(n, c, w, v)
    # [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    # [0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2]
    # [0, 0, 3, 3, 5, 5, 5, 5, 5, 5, 5]
    # [0, 0, 3, 3, 5, 5, 5, 6, 6, 6, 6]
    # [0, 5, 5, 8, 8, 10, 10, 10, 11, 11, 11]
    # [0, 5, 5, 8, 8, 10, 10, 10, 12, 12, 14]
    # [0, 5, 5, 8, 8, 11, 11, 13, 13, 13, 15]
    show(n, c, w, value)
    # 最大价值为: 15
    # 背包中所装物品为:
    # 第 2 个,第 4 个,第 5 个,第 6 个,
    print('\n空间复杂度优化为N(c)结果:', bag1(n, c, w, v))
    #空间复杂度优化为N(c)结果: [0, 5, 5, 8, 8, 11, 11, 13, 13, 13, 15]

如有错误,欢迎指正和交流~

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/164409.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 编写两分钟的倒计时c语言(c语言倒计时几分几秒)

    集团文件版本号:(M928-T898-M248-WU2669-I2896-DQ586-M1988)集团文件版本号:(M928-T898-M248-WU2669-I2896-DQ586-M1988)C语言分钟倒计时代码C语言-2分钟倒计时代码#include#include#includeintmain(){inta=1,i=59;printf(“2:00”);Sleep(1000);sy…

    2022年4月17日
    133
  • leetcode题目分类_最长前缀匹配例题

    leetcode题目分类_最长前缀匹配例题原题链接编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 “”。示例 1:输入:strs = [“flower”,”flow”,”flight”]输出:”fl”示例 2:输入:strs = [“dog”,”racecar”,”car”]输出:””解释:输入不存在公共前缀。 提示:0 <= strs.length <= 2000 <= strs[i].length <= 200strs[i] 仅由小写英文字母组成题解分

    2022年8月8日
    10
  • 什么叫应用程序域?(zhuan)

    什么叫应用程序域?(zhuan) 一:应用程序域介绍:    "域",就是范围,环境,边界的意思,那么什么是应用程序域,官方给出的是这样的解释:操作系

    2022年7月3日
    17
  • Ubuntu 搭建opengrok 流程

    Ubuntu 搭建opengrok 流程opengrok平台搭建流程软件下载链接:https://pan.baidu.com/s/1kCeXNlj2l3FujyMza3rM0w提取码:iniy搭建前的准备电脑系统电脑系统推荐使用ubuntu16,这版系统较为稳定。细节未更新python环境推荐使用python2.7及以上版本,这一版本相对稳定,python安装细节未更新java环境推荐使用JDK1.8及以上版本,具体安装细节未更新通过java-version和javac-version可以查看版本。Ope

    2022年5月27日
    79
  • idea打不开,点击后无反应,多次重装无效解决办法。

    idea打不开,点击后无反应,多次重装无效解决办法。昨天更新了新版本idea,然后直接用激活码激活了,应用了旧版本的配置,当时用着没问题,后来删除掉了旧版本的安装目录,今天再打开idea时候多次点击无反应,多次重装无效,然后开始寻找解决办法。百度之后很多人反映是idea64.exe.vmoptions和idea.exe.vmoptions文件中,当时激活成功教程时候加的激活成功教程文件路径找不到报错的原因,然而检查后发现并没有激活成功教程文件的路径,最后试着在idea…

    2022年8月30日
    6
  • 跨境电商ERP源码

    亚马逊企业购2021战略品类首发,万亿商采风口不容错过!由于电子信息技术和经济全球化的进一步发展,电子商务在国际贸易中的影响力和关键作用日渐突显,已变成中国出口贸易的市场趋势。跨境电商未来的发展前景必定是有助于减少经济成本、推动全球贸易便利化,有助于提高国内群众福祉,有助于打造良好的营商环境推动经济长期健康发展。从2015年开始截止到2019年底,国务院共先后发布了4批全国跨境电商综试区名单。到目前为止,全国有多少个跨境电商综试区?综试区名单批次清单如下:第一批跨境电子商务综合试验区:201

    2022年4月5日
    267

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号