实验二贪心算法_第1页
实验二贪心算法_第2页
实验二贪心算法_第3页
实验二贪心算法_第4页
实验二贪心算法_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

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

文档简介

1、实验二 贪心法(4学时)上机实验一般应包括以下几个步骤:(1)、准备好上机所需的程序。手编程序应书写整齐,并经人工检查无误后才能上机。(2)、上机输入和调试自己所编的程序。一人一组,独立上机调试,上机时出现的问题,最好独立解决。(3)、上机结束后,整理出实验报告。实验报告应包括:题目、程序清单、运行结果、对运行情况所作的分析。一、实验目的与要求1. 掌握贪心法的基本思想方法;2. 了解适用于用贪心法求解的问题类型,并能设计相应贪心法算法;3. 掌握贪心算法复杂性分析方法分析问题复杂性。二、实验内容:1、哈夫曼编码 设需要编码的字符集为d1, d2, , dn,它们出现的频率为w1, w2, ,

2、 wn,应用哈夫曼树构造最短的不等长编码方案。设计贪心算法求解此哈夫曼编码方案; 2、删数问题键盘输入一个高精度的正整数n(n<10位)去掉任意s个数字后剩下的数字按原左右次序组成一个新的正整数。编程对给定的n和s,寻找一种方案,使得剩下的数最小。3、贪心背包问题 已知一个容量为M的包和n件物品, 每件物品的重量为wi, 效益值为pi. 若将物品i的一部分0xi1装入包中, 背包可得到pixi的效益值增量. 要求找到一种装入物品的方案, 在不超过包的总容量前提下, 使包获得最大效益值。三、实验步骤1 理解算法思想和问题要求;2 编程实现题目要求;3 上机输入和调试自己所编的程序;4 验证

3、分析实验结果;5 整理出实验报告。四、实验要求1)上述题目任选两道做。2)独立完成程序代码的编写3)独立完成实验及实验报告附:实验报告的主要内容一实验目的二问题描述三解题思路四算法设计包含:数据结构与核心算法的设计描述、函数调用及主函数设计、主要算法流程图等五.程序调试及运行结果分析六.实验总结附录:程序清单 (程序过长,只附主要部分)五、实验原理贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最优解或者是整体最

4、优解的近似解。A、贪心算法的基本思路1.建立数学模型来描述问题。2.把求解的问题分成若干个子问题。3.对每一子问题求解,得到子问题的局部最优解。4.把子问题的解局部最优解合成原来解问题的一个解。B、实现该算法的过程:从问题的某一初始解出发;while 能朝给定总目标前进一步 do求出可行解的一个解元素;由所有解元素组合成问题的一个可行解。C、贪心算法的适用的问题:贪心算法适用的问题必须满足两个属性:()贪心性质:整体的最优解可通过一系列局部最优解达到,并且每次的选择可以依赖以前做出的选择,但不能依赖于以后的选择。()最优子结构:问题的整体最优解包含着它的子问题的最优解。D、贪心算法的基本步骤(

5、)分解:将原问题分解为若干相互独立的阶段。()解决:对于每一个阶段求局部的最优解。()合并:将各个阶段的解合并为原问题的解。附注:部分实验代码1、哈夫曼编码数据结构与算法typedef char *HuffmanCode; /动态分配数组,存储哈夫曼编码typedef struct unsigned int weight; /用来存放各个结点的权值 unsigned int parent,LChild,RChild; /指向双亲、孩子结点的指针 HTNode, *HuffmanTree; /动态分配数组,存储哈夫曼树核心源代码#include <stdio.h>#include &

6、lt;stdlib.h>#include <string.h>typedef struct unsigned int weight; /用来存放各个结点的权值 unsigned int parent,LChild,RChild; /指向双亲、孩子结点的指针 HTNode, *HuffmanTree; /动态分配数组,存储哈夫曼树typedef char *HuffmanCode; /动态分配数组,存储哈夫曼编码/选择两个parent为0,且weight最小的结点s1和s2void Select(HuffmanTree *ht,int n,int *s1,int *s2) in

7、t i,min; for(i=1; i<=n; i+) if(*ht)i.parent=0) min=i; break; for(i=1; i<=n; i+) if(*ht)i.parent=0) if(*ht)i.weight<(*ht)min.weight) min=i; *s1=min; for(i=1; i<=n; i+) if(*ht)i.parent=0 && i!=(*s1) min=i; break; for(i=1; i<=n; i+) if(*ht)i.parent=0 && i!=(*s1) if(*ht)i.

8、weight<(*ht)min.weight) min=i; *s2=min;/构造哈夫曼树ht,w存放已知的n个权值void CrtHuffmanTree(HuffmanTree *ht,int *w,int n) int m,i,s1,s2; m=2*n-1; /总共的结点数 *ht=(HuffmanTree)malloc(m+1)*sizeof(HTNode); for(i=1; i<=n; i+) /1-n号存放叶子结点,初始化 (*ht)i.weight=wi; (*ht)i.LChild=0; (*ht)i.parent=0; (*ht)i.RChild=0; for(

9、i=n+1; i<=m; i+) /非叶子结点的初始化 (*ht)i.weight=0; (*ht)i.LChild=0; (*ht)i.parent=0; (*ht)i.RChild=0; printf("n哈夫曼树为: n"); for(i=n+1; i<=m; i+) /创建非叶子结点,建哈夫曼树 /在(*ht)1(*ht)i-1的范围内选择两个parent为0且weight最小的结点,其序号分别赋值给s1、s2 Select(ht,i-1,&s1,&s2); (*ht)s1.parent=i; (*ht)s2.parent=i; (*ht

10、)i.LChild=s1; (*ht)i.RChild=s2; (*ht)i.weight=(*ht)s1.weight+(*ht)s2.weight; printf("%d (%d, %d)n",(*ht)i.weight,(*ht)s1.weight,(*ht)s2.weight); printf("n"); /从叶子结点到根,逆向求每个叶子结点对应的哈夫曼编码void CrtHuffmanCode(HuffmanTree *ht, HuffmanCode *hc, int n) char *cd; /定义的存放编码的空间 int a100; int

11、 i,start,p,w=0; unsigned int c; hc=(HuffmanCode *)malloc(n+1)*sizeof(char *); /分配n个编码的头指针 cd=(char *)malloc(n*sizeof(char); /分配求当前编码的工作空间 cdn-1='0' /从右向左逐位存放编码,首先存放编码结束符 for(i=1; i<=n; i+) /求n个叶子结点对应的哈夫曼编码 ai=0; start=n-1; /起始指针位置在最右边 for(c=i,p=(*ht)i.parent; p!=0; c=p,p=(*ht)p.parent) /从

12、叶子到根结点求编码 if( (*ht)p.LChild=c)cd-start='1' /左分支标1ai+; else cd-start='0' /右分支标0ai+; hci=(char *)malloc(n-start)*sizeof(char); /为第i个编码分配空间 strcpy(hci,&cdstart); /将cd复制编码到hc free(cd); for(i=1; i<=n; i+) printf(" 权值为%d的哈夫曼编码为:%sn",(*ht)i.weight,hci); for(i=1; i<=n; i+

13、) w+=(*ht)i.weight*ai; printf(" 带权路径为:%dn",w);void main() HuffmanTree HT; HuffmanCode HC; int *w,i,n,wei; printf("*哈夫曼编码*n" ); printf("请输入结点个数:" ); scanf("%d",&n); w=(int *)malloc(n+1)*sizeof(int); printf("n输入这%d个元素的权值:n",n); for(i=1; i<=n; i+

14、) printf("%d: ",i); fflush(stdin); scanf("%d",&wei); wi=wei; CrtHuffmanTree(&HT,w,n); CrtHuffmanCode(&HT,&HC,n);2、删数问题#include<stdio.h>int Del(int D,int a10,int n)/D 删除几位 a 数组 n 当前数组位数int res,max,i,j,x10;for(i=0;i<n;i+)xi=an-i-1;while(1)if(D=0)break;elseD

15、-;max=0;j=0;for(i=0;i<n;i+)if(max<xi)max=xi;j=i;n-;for(i=j;i<n;i+)xi=xi+1;res=0;for(i=0;i<n;i+)res=res*10+xi;return(res); void main()int Res,D,z,n,m,i,a10;/m=43252556;i=0;n=0;printf("<-删数问题->n");printf("请输入一个高精度的正整数N(N<=10位):");scanf("%d",&m);pr

16、intf("请输入要去掉数字的位数S(S<=N):");scanf("%d",&D);while(1)z=m/10;ai=m-z*10;m=z;i+;n+;if(m=0)break;Res=Del(D,a,n);printf("删除后的结果为:");printf("%dn",Res);3贪心背包问题#include <iostream.h> #include<iomanip.h> #include<string.h> int min(int w,int c) int

17、 temp; if (w<c) temp=w; else temp=c; return temp; int max(int w,int c) int temp; if (w>c) temp=w; else temp=c; return temp; void knapsack(int v,int w,int c,int n,int*m) /求最优值 int jmax=min(wn-1,c); for(int j=0;j<=jmax;j+) mnj=0; for(int jj=wn;jj<=c;jj+) mnjj=vn; for(int i=n-1;i>1;i-) /

18、递归部分 jmax=min(wi-1,c); for(int j=0;j<=jmax;j+) mij=mi+1j; for(int jj=wi;jj<=c;jj+) mijj=max(mi+1jj,mi+1jj-wi+vi); m1c=m2c; if(c>=w1) m1c=max(m1c,m2c-w1+v1); cout<<"最优值:"<<m1c<<endl; cout<<endl; int traceback(int *m,int w,int c,int n,int x) /回代,求最优解 cout<<"得到的一组最优解如下:&qu

温馨提示

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

评论

0/150

提交评论