实验3动态规划_第1页
实验3动态规划_第2页
实验3动态规划_第3页
实验3动态规划_第4页
实验3动态规划_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、实验二 贪心法(4学时)上机实验一般应包括以下几个步骤:(1)、准备好上机所需的程序。手编程序应书写整齐,并经人工检查无误后才能上机。(2)、上机输入和调试自己所编的程序。一人一组,独立上机调试,上机时出现的问题,最好独立解决。(3)、上机结束后,整理出实验报告。实验报告应包括:题目、程序清单、运行结果、对运行情况所作的分析。一、实验目的与要求1. 掌握动态规划法的基本思想方法;理解动态规划的基本思想,理解动态规划算法的两个基本要素最优子结构性质和子问题的重叠性质。熟练掌握典型的动态规划问题。2. 了解适用于用动态规划法求解的问题类型,并能设计相应动态规划法算法;3. 掌握动态规划算法复杂性分

2、析方法分析问题复杂性。二、实验内容(以下题目要求采用动态规划算法完成):1、找零钱问题设有n种不同面值的硬币,各硬币的面值存于数组T1:n中。现要用这些面值的硬币来找钱,可以实用的各种面值的硬币个数不限。当只用硬币面值T1,T2,Ti时,可找出钱数j的最少硬币个数记为C(i,j)。若只用这些硬币面值,找不出钱数j时,记C(i,j)=。 设计一个动态规划算法,对1jL,计算出所有的C( n,j )。算法中只允许实用一个长度为L的数组。用L和n作为变量来表示算法的计算时间复杂性2、最大子段和问题给定由n个整数组成的序列(a1, a2, , an),求该序列形如 的子段和的最大值,当所有整数均为负整

3、数时,其最大子段和为0。如序列为(-20,11,-4,13,-5)其最大子段和为20对应子段为 (11,-4,13)3、数塔问题有N件物品和一个容量为V的背包。第i件物品的重量是ci,价值是wi。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。三、实验步骤1 理解算法思想和问题要求;2 编程实现题目要求;3 上机输入和调试自己所编的程序;4 验证分析实验结果;5 整理出实验报告。四、实验要求1)上述题目任选两道做。2)独立完成程序代码的编写3)独立完成实验及实验报告附:实验报告的主要内容一实验目的二问题描述三解题思路四算法设计包含:数据结构与核心算法的设计描述、函数

4、调用及主函数设计、主要算法流程图等五.程序调试及运行结果分析六.实验总结附录:程序清单 (程序过长,只附主要部分)五、实验原理(一)、动态规划的基本思想: 动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的

5、子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路。具体的动态规划算法多种多样,但它们具有相同的填表格式。 二、设计动态规划法的步骤: 1、找出最优解的性质,并刻画其结构特征; 2、递归地定义最优值(写出动态规划方程); 3、以自底向上的方式计算出最优值; 4、根据计算最优值时得到的信息,构造一个最优解。 步骤1-3是动态规划算法的基本步骤。在只需要求出最优值的情形,步骤4可以省略,步骤3中记录的信息也较少;若需要求出问题的一

6、个最优解,则必须执行步骤4,步骤3中记录的信息必须足够多以便构造最优解。 三、动态规划问题的特征: 动态规划算法的有效性依赖于问题本身所具有的两个重要性质:最优子结构性质和子问题重叠性质。 1、最优子结构:当问题的最优解包含了其子问题的最优解时,称该问题具有最优子结构性质。 2、重叠子问题:在用递归算法自顶向下解问题时,每次产生的子问题并不总是新问题,有些子问题被反复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只解一次,而后将其解保存在一个表格中,在以后尽可能多地利用这些子问题的解。(二)、动态规划算法的基本步骤 设计一个标准的动态规划算法,通常可按以下几个步骤进行:

7、1. 划分阶段:按照问题的时间或空间特征,把问题分为若干个阶段。注意这若干个阶段一定要是有序的或者是可排序的(即无后向性),否则问题就无法用动态规划求解。 2. 选择状态:将问题发展到各个阶段时所处于的各种客观情况用不同的状态表示出来。当然,状态的选择要满足无后效性。 3. 确定决策并写出状态转移方程:之所以把这两步放在一起,是因为决策和状态转移有着天然的联系,状态转移就是根据上一阶段的状态和决策来导出本阶段的状态。所以,如果我们确定了决策,状态转移方程也就写出来了。但事实上,我们常常是反过来做,根据相邻两段的各状态之间的关系来确定决策。 4. 写出规划方程(包括边界条件):动态规划的基本方程

8、是规划方程的通用形式化表达式。一附注:部分实验代码1、找零钱for (i=0;i<kind;i+)for (j=i+1;j<kind;j+)if (Ti>Tj)Swap(Ti,Tj);long temptotal=total;if (total>0)for (i=kind-1;i>=0;i-)Swap(Ti,Tkind-1);if (Tkind-1>0)ckind-1=temptotal/Tkind-1;long tempcount=0;while(ckind-1>0)&&(ckind-1<=mincount)tempcount=

9、ckind-1;temptotal=temptotal-Tkind-1*ckind-1;for (j=kind-2;j>=0;j-)if (temptotal>0)&&(Tj>0)cj=temptotal/Tj;temptotal=temptotal-Tj*cj;tempcount=tempcount+cj;if (tempcount>0)&&(tempcount<mincount)&&(temptotal=0)mincount=tempcount;ckind-1=ckind-1-1;temptotal=total;

10、tempcount=0;2、最大子段和问题void MaxSum(int n,int a) int sum=0; int b=0; for(int i=1;i<=n;i+) if(b>0)b+=ai; else b=ai; if(b>sum)sum=b; 3、0-1背包问题#include <stdio.h>#include <malloc.h>typedef structint object;int weight;int value;KnapSack;KnapSack * knapsack; /背包数组,用malloc或new动态创建int num;

11、 /物体的个数int container; /背包的最大容量int * array=NULL; /用来存放子问题的结果/动态创建背包void Create_KnapSack()char c;printf("input the number of objectsn");scanf("%d", &num);knapsack=new KnapSacknum+1;printf("input weight and value of %d objects, like 1:4 10n", num);for(int i=1; i<=nu

12、m; i+)scanf("%d%c%d%c%d",&knapsacki.object,&c,&knapsacki.weight,&c,&knapsacki.value);getchar(); /为了获取空格或其他输入int k= knapsacknum.value;printf("%d",k);printf("input the volume of the knapsack:n");scanf("%d", &container);/确定最优子问题void Resolv

13、e_KnapSack()int k=knapsacknum.value;printf("%d", k);/创建动态二维数组mnumcontainerarray=(int *)malloc(num+1)*sizeof(int *);for(int i=0; i<=num; i+)arrayi=(int *)malloc(container+1)*sizeof(int);/for(int j=0; j<=container; j+)arraynumj = (j>=knapsacknum.weight)? knapsacknum.value : 0;/子问题的最

14、优结果for(int m=num-1; m>0; m-)for(int n=0; n<=container; n+)if( n > knapsackm.weight && arraym+1n<=arraym+1n- knapsackm.weight+knapsackm.value)arraymn=arraym+1n-knapsackm.weight+knapsackm.value;/else包括两种情况,共同点是该物体没有被使用elsearraymn=arraym+1n;/往回找,确定某个物体i是否被使用bool * Trace_back()int c=

15、container;bool * used;used=(bool *)malloc(sizeof(bool)*(num+1);for(int i=1; i<num; i+)if(arrayic=arrayi+1c)usedi=0;elseusedi=1;c-=knapsacki.weight;usednum= (c=knapsacknum.weight)? 1:0;return used;/用来输出被使用的物体及其相关值void Print_KnapSack(bool * used)printf("the objects used as follows:n");for

16、(int i=1; i<=num; i+)if(usedi)printf("%d:%d %dn", knapsacki.object,knapsacki.weight,knapsacki.value);void main()bool * used;Create_KnapSack();Resolve_KnapSack();used=Trace_back();Print_KnapSack(used);/#include<stdio.h>#include<iostream>using namespace std;#define kind 7void

17、main()int i,j;int m=1;int temp;int Tkind=1,5,2,10,20,50,100;int ckind=0; long total;int mincount=1000;cout<<"请输入要找开的钱数:"cin>>total;for (i=0;i<kind-1;i+)for (j=i+1;j<kind;j+)if (Ti>Tj)/Swap(Ti,Tj);temp=Ti;Ti=Tj;Tj=temp;for(i=0;i<kind;i+)cout<<"t"<&

18、lt;i<<""<<Ti<<endl;/mincount=10000;long temptotal=total;if (total>0)for (i=kind-1;i>=0;i-)/Swap(Ti,Tkind-1);temp=Ti;Ti=Tkind-1;Tkind-1=temp;if (Tkind-1>0)ckind-1=temptotal/Tkind-1;long tempcount=0;while(ckind-1>0)&&(ckind-1<=mincount)tempcount=ckind

19、-1;temptotal=temptotal-Tkind-1*ckind-1;for (j=kind-2;j>=0;j-)if (temptotal>0)&&(Tj>0)cj=temptotal/Tj;temptotal=temptotal-Tj*cj;tempcount=tempcount+cj;if (tempcount>0)&&(tempcount<mincount)&&(temptotal=0)mincount=tempcount;else ckind-1=ckind-1-1;temptotal=total;tempcount=0;/m+;cout<<"硬币个数是:"<<

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论