代码链接: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个物品放到背包里获得的最大价值),此时我们便有两种选择:
两种选择中总价值最大的方案就是我们的最终方案,递推式(状态转移方程)如下:
①编写数据数据生成函数,生成几组不同规模数据; ②将用例数据从文件中读取到数组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); | ||||
实验心得 | 通过这次实验,我回顾了动态规划算法的基本原理,通过编程实现动规思想,让我熟悉了动规算法的用法,更好的理解了动态规划的过程。 实验可改进的地方: 一个是算法所给的质量是整数,一个是当当背包容量很大时,算法所需计算时间比较多; |