01背包问题----动态规划 -----python代码、优化

这篇具有很好参考价值的文章主要介绍了01背包问题----动态规划 -----python代码、优化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

问题描述:

容量为C的背包选择装物品,有n个物品,它们有各自的体积wi和价值vi,如何让背包里装入的物品具有最大价值?

解题思路:

也就是n个物品选择装入背包,每个物品都有两种选择,是(1)或否(0),

建模:       xi表示当前第i个物品是否选择,xi取值为(0,1)。

        约束条件:,选择的物品重量小于等于C,且这几样物品加起来的价值最大。

动态规划:

           动态规划算法通常用于求解具有某种最优性质的问题。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算。我们可以用一个表来记录所有已解的子问题的答案,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路

         适用动态规划的问题必须满足最优化原理和无后效性  。 最优化原理(最优子结构性质)

          最优化原理可这样阐述:一个最优化策略具有这样的性质,不论过去状态和决策如何,对前面的决策所形成的状态而言,余下的诸决策必须构成最优策略。简而言之,一个最优化策略的子策略总是最优的。一个问题满足最优化原理又称其具有最优子结构性质。

          无后效性 将各阶段按照一定的次序排列好之后,对于某个给定的阶段状态,它以前各阶段的状态无法直接影响它未来的决策,而只能通过当前的这个状态。换句话说,每个状态都是过去历史的一个完整总结。这就是无后向性,又称为无后效性。

           动态规划没有统一的处理方法,必须根据问题的各种性质并结合一定的技巧来处理,一般最常见的就是用公式求出每个位置的最大值,然后用二维列表保存,这是最基础的,之后再想办法优化。

python动态规划解决 古堡探险,动态规划,算法,python

         

递推关系:

1、V(i,j):当前背包容量 j,前 i 个物品最佳组合对应的最大价值

首先对当前第i个物品是否选择装,背包容量装不下当前物品,所以选择不装,所以当前最大价值就是前i-1个物品时的最大价值。V(i-1,j)

2如果背包容量可以装下当前的物品,就需要判断是否装。

max(不装v(i-1,j),  ),也就是不装时最大价值等于前i-1个物品时的最大价值,装就是最大价值等于装下的这个物品的价值加上背包容量为(j-wi)(减去当前这个物品的wi)时能装前i-1个物品时的最大价值(vij-wi),选取两者的最大值。

python动态规划解决 古堡探险,动态规划,算法,python

举例:4个物品:python动态规划解决 古堡探险,动态规划,算法,python 

 通过填表的方式:

python动态规划解决 古堡探险,动态规划,算法,python

 追踪解:

python动态规划解决 古堡探险,动态规划,算法,python

 如果当前i个物品的最大价值和前i-1个东西的最大价值一样时,说明第i个物品没放,则x;=0。反之当前i个物品的最大价值大于前i-1个物品的最大价值时,说明放了第i个物品,则x;=1。

python动态规划解决 古堡探险,动态规划,算法,python

 代码:(Python):

def bag(n, c, w, v):
    res = [[0 for j in range(c + 1)] for i in range(n + 1)]#初始值全赋值为0
    for i in range(1, n + 1):
        for j in range(1, c + 1):
            res[i][j] = res[i - 1][j]#根据公式填写表,得到最大收益
            if j >= w[i - 1] and res[i][j] < res[i - 1][j - w[i - 1]] + v[i - 1]:
                res[i][j] = res[i - 1][j - w[i - 1]] + v[i - 1]
    return res
def show(n, c, w, res):
    print('最大收益为:', res[n][c])
    x = [False for i in range(n)]
    j = c
    for i in range(1, n + 1):  # (1,6)
        if res[i][j] > res[i - 1][j]:#判断项目是否投资
            x[i - 1] = True
            j -= w[i - 1] #投资后(资金-当前金额投资)
    print('选择的项目为:')
    for i in range(n):
        if x[i]:
            print('第', i + 1, '个,', end='') #展示结果
    print('')
#实例
n = 5
c = 10
w = [2, 2, 6, 5, 4]
v = [6, 3, 5, 4, 6]
res = bag(n, c, w, v)
show(n, c, w, res)

利用动态规划解决此问题的效率即是填写此张表的效率,所以动态规划的 时间效率为O(number*capacity)=O(n*c),

由于用到二维数组存储子问题的解,所以动态规划的 空间效率为O(n*c);

 文章来源地址https://www.toymoban.com/news/detail-767371.html

优化,从上述的填表的过程中,我们可以发现vij的值只与上一行有关。

可以将V缩减成一维数组,从而达到优化空间的目的,状态转移方程转换为 B(j)= max{B(j), B(j-w(i))+v(i)}; 每一次推导V(i)(j)是通过V(i-1)(j-w(i))来推导的,所以要保留上一行前面的值。所以一维数组中j的扫描顺序应该从大到小(capacity到0),否者前一次循环保存下来的值将会被修改,从而造成错误。

 

到了这里,关于01背包问题----动态规划 -----python代码、优化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 动态规划-01背包问题(python)

    对于动态规划问题,就是牺牲空间来提高时间,通过将一个个小问题的答案存储起来,直接供给后面问题求解,避免重复的运算,从而提高效率,这就是动态规划的思想。 下面我们通过一个经典的01背包问题来了解动态规划的解题方法吧(文末附上完整代码) 首先,将每个物

    2024年02月06日
    浏览(43)
  • 动态规划01背包问题-代码随想录-刷题笔记

    有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。 每件物品只能用一次 ,求解将哪些物品装入背包里物品价值总和最大。 二维dp数组01背包 确定dp数组以及下标的含义 是使用二维数组,即 dp[i][j] 表示从下标为[0-i]的物品里任意取,

    2024年02月07日
    浏览(58)
  • 【Java实现】动态规划算法解决01背包问题

    1、问题描述: 一个旅行者有一个最多能装m公斤的背包,现在有n中物品,每件的重量分别是W1、W2、……、Wn,每件物品的价值分别为C1、C2、……、Cn, 需要将物品放入背包中,要怎么样放才能保证背包中物品的总价值最大? 2、动态规划算法的概述 1)动态规划(Dynamic Progra

    2023年04月09日
    浏览(57)
  • 01背包问题三种解决(贪心动态规划分支限界)

    一、实验目的 1、深入理解背包相关问题。 2、能正确设计相应的算法,解决实际问题。   3、掌握算法时间复杂度分析。 二、实验要求 用3种方法求解0-1背包问题(贪心算法、 动态规划、分支限界法 ),获得精确最优解或近似最优解均可。 通过一个规模较大的实例比较不同

    2024年02月02日
    浏览(58)
  • 动态规划:0-1背包、完全背包问题 | 详细原理解释 | 代码及优化(C++)

    目录 01背包 问题描述: 简单描述就是: 解析: 递推公式: dp数组的初始化: 遍历顺序: 图解: 实现代码: dp数组初始化: 遍历: 优化: 原理: 递推公式: 遍历顺序: 实现代码: 初始化: 遍历: 完全背包 问题描述: 解析: 实现代码:         01背包是在M件物品

    2024年02月11日
    浏览(37)
  • 代码随想录 Day35 动态规划04 01背包问题和完全背包问题 LeetCode T416 分割等和子集

    说到背包问题大家都会想到使用动规的方式来求解,那么为什么用动规呢, dp数组代表什么呢 ? 初始化是什么 , 遍历方式又是什么 ,这篇文章笔者将详细讲解背包问题的经典例题0-1背包问题和完全背包问题的解题方式,希望能帮助到大家 有人一提到背包问题就只会使用动态规划来

    2024年02月06日
    浏览(76)
  • 【动态规划专栏】-- 01 背包问题 -- 动态规划经典题型

    目录 背包问题概述 01 背包问题 01背包⭐⭐  【算法原理】 第一问 第二问 C++ 算法代码 复杂度分析 【空间优化 - 滚动数组】 C++ 算法代码 复杂度分析 分割等和子集⭐⭐ 【算法原理】  对于类01背包问题 C++ 算法代码  【空间优化 - 滚动数组】  C++ 算法代码 目标和⭐⭐ 【算

    2024年02月05日
    浏览(57)
  • 【第二十五课】动态规划:完全背包问题(acwing-3 / 公式推导 / 思路理解 / 优化 / c++代码)

    目录 思路 朴素代码 优化 公式推导上  二维代码  一维代码 公式理解上   在开始看完全背包问题之前,可能需要先了解01背包及其解决办法。 指路👇 【第二十五课】动态规划:01背包问题(acwing-2 / 思路 / 含一维数组优化 / c++代码) 这个问题和01背包的区别就是 每件物品可以

    2024年03月19日
    浏览(64)
  • 动态规划_01背包问题

    描述 一个旅行者有一个最多能装   M   公斤的背包,现在有   n   件物品,它们的重量分别是   W 1 ​ , W 2 ​ , ... , W n ​ , 它们的价值分别为   C 1 ​ , C 2 ​ , ... , C n ​ ,求旅行者能获得最大总价值。 输入描述 第 1 行:两个整数, M   (背包容量, M ≤ 200   )和   N  

    2024年04月29日
    浏览(40)
  • 动态规划:01背包问题(二)

    上篇博客动态规划:01背包问题(一)将的是用二维数组来解决,而本篇博客就是把二维dp数组降为一维dp数组(滚动数组)在使用二维数组的时候,递推公式:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); 其实可以发现如果 把dp[i - 1]那一层拷贝到dp[i]上 ,表达式完全可以是

    2024年01月22日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包