算法分析二(1)——用动规法实现 0-1 背包

代码链接:pan.baidu.com/s/1rIugypf7lhUTfwdAG0Gv_w 
码:w38a 

算法分析与设计

时间

2020.4.22

实验名称

用动规法实现 0-1 背包

实验目的

通过上机实验,要求掌握动态规划算法的问题描述、算法设计思想、程序设计。

实验原理

利用动态规划法求解 0-1 背包问题,并计算出程序运行所需要的时间。

实验步骤

问题分析

0-1背包问题形式化的描述是,给定c > 0, wi, vi, 1 <= i <= n(c为背包容量), 要找出一个n元0-1向量(x1, x2, ... , xn),xi ∈ {0, 1}, 1 <= i <= n, 使得∑ wixi (i 从 1 到 n 求和)<= c ,而且∑ wixi (i 从 1 到 n 求和)达到最大。

因此0-1背包问题是一个特殊的整数规划问题。

动态规划思想:

用m(i,j)表示将第i到n个物品放进容量为j的背包里,得到的最大的价值。

我们用自顶向下的角度来看,假如我们已经进行到了最后一步(即求解将n个物品放到背包里获得的最大价值),此时我们便有两种选择:

  1. 不放第1个物品,此时总价值为m(2,j)
  2. 放置第1个物品,此时总价值为vn+m(2,j−w1)

两种选择中总价值最大的方案就是我们的最终方案,递推式(状态转移方程)如下:

  • 解题思路

①编写数据数据生成函数,生成几组不同规模数据;

②将用例数据从文件中读取到数组v、w中;

③初始化保存子问题解的 m 数组;

④根据状态转移方程,从物品i为最大n开始向前遍历求解子问题,遍历j,求解对应的m(i,j)的值,做如下操作:

如果j>w[i],说明物品i可以放入容量为j的背包,考虑其放入与不放入的两种情况并取最大值;

如果j<w[i],说明物品i无法放入背包,只需要将m[i][j]=m[i+1][j]即可;

⑤当i从n遍历到1结束,m[1][c]即为所求解;

关键代码

关键代码(带注释)

1. 动规部分代码(核心)

 

完全按照状态转移方程来求解子问题,到达i=1时,i=2层的子问题的解已知,可以直接求解m[1][c]而不用再求解i=1层的其他子问题解;

2. 文件读取函数

通过输入的格式读出数据到数组中;

3. 随机数生成函数

利用rand函数生成大小为10、100、1000的三个文件,其中为随机数;

测试结果

运行结果截图及分析

例题结果:

输入输出文件:

结果运行正确;

选择了(2,6)、(2,3)、(4、6);

三种数据规模(10、100、1000)结果分析

程序段运行时间的单位为ms,数据规模越大,运行时间越长;

时间复杂度分析:

从递归式知道需要求解n*c个子问题的解,每一个问题的求解都是O(1)的,因此,总的时间复杂度为O(nc);

实验心得

通过这次实验,我回顾了动态规划算法的基本原理,通过编程实现动规思想,让我熟悉了动规算法的用法,更好的理解了动态规划的过程。

实验可改进的地方:

一个是算法所给的质量是整数,一个是当当背包容量很大时,算法所需计算时间比较多;

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值