北邮-算法设计和分析-第三章实验报告

合集下载

算法设计与分析实验报告三篇

算法设计与分析实验报告三篇

算法设计与分析实验报告一实验名称统计数字问题评分实验日期2014 年11 月15 日指导教师姓名专业班级学号一.实验要求1、掌握算法的计算复杂性概念。

2、掌握算法渐近复杂性的数学表述。

3、掌握用C++语言描述算法的方法。

4.实现具体的编程与上机实验,验证算法的时间复杂性函数。

二.实验内容统计数字问题1、问题描述一本书的页码从自然数1 开始顺序编码直到自然数n。

书的页码按照通常的习惯编排,每个页码都不含多余的前导数字0。

例如,第6 页用数字6 表示,而不是06 或006 等。

数字计数问题要求对给定书的总页码n,计算出书的全部页码中分别用到多少次数字0,1,2, (9)2、编程任务给定表示书的总页码的10 进制整数n (1≤n≤109) 。

编程计算书的全部页码中分别用到多少次数字0,1,2, (9)三.程序算法将页码数除以10,得到一个整数商和余数,商就代表页码数减余数外有多少个1—9作为个位数,余数代表有1—余数本身这么多个数作为剩余的个位数,此外,商还代表1—商本身这些数出现了10次,余数还代表剩余的没有计算的商的大小的数的个数。

把这些结果统计起来即可。

四.程序代码#include<iostream.h>int s[10]; //记录0~9出现的次数int a[10]; //a[i]记录n位数的规律void sum(int n,int l,int m){ if(m==1){int zero=1;for(int i=0;i<=l;i++) //去除前缀0{ s[0]-=zero;zero*=10;} }if(n<10){for(int i=0;i<=n;i++){ s[i]+=1; }return;}//位数为1位时,出现次数加1//位数大于1时的出现次数for(int t=1;t<=l;t++)//计算规律f(n)=n*10^(n-1){m=1;int i;for(i=1;i<t;i++)m=m*10;a[t]=t*m;}int zero=1;for(int i=0;i<l;i++){ zero*= 10;} //求出输入数为10的n次方int yushu=n%zero; //求出最高位以后的数int zuigao=n/zero; //求出最高位zuigaofor(i=0;i<zuigao;i++){ s[i]+=zero;} //求出0~zuigao-1位的数的出现次数for(i=0;i<10;i++){ s[i]+=zuigao*a[l];} //求出与余数位数相同的0~zuigao-1位中0~9出现的次数//如果余数是0,则程序可结束,不为0则补上所缺的0数,和最高位对应所缺的数if(yushu==0) //补上所缺的0数,并且最高位加1{ s[zuigao]++;s[0]+=l; }else{ i=0;while((zero/=10)>yushu){ i++; }s[0]+=i*(yushu+1);//补回因作模操作丢失的0s[zuigao]+=(yushu+1);//补回最高位丢失的数目sum(yushu,l-i-1,m+1);//处理余位数}}void main(){ int i,m,n,N,l;cout<<"输入数字要查询的数字:";cin>>N;cout<<'\n';n = N;for(i=0;n>=10;i++){ n/=10; } //求出N的位数n-1l=i;sum(N,l,1);for(i=0; i<10;i++){ cout<< "数字"<<i<<"出现了:"<<s[i]<<"次"<<'\n'; }}五.程序调试中的问题调试过程,页码出现报错。

算法设计与分析实验报告_3

算法设计与分析实验报告_3

实验一全排列、快速排序【实验目的】1.掌握全排列的递归算法。

2.了解快速排序的分治算法思想。

【实验原理】一、全排列全排列的生成算法就是对于给定的字符集, 用有效的方法将所有可能的全排列无重复无遗漏地枚举出来。

任何n个字符集的排列都可以与1~n的n个数字的排列一一对应, 因此在此就以n个数字的排列为例说明排列的生成法。

n个字符的全体排列之间存在一个确定的线性顺序关系。

所有的排列中除最后一个排列外, 都有一个后继;除第一个排列外, 都有一个前驱。

每个排列的后继都可以从它的前驱经过最少的变化而得到, 全排列的生成算法就是从第一个排列开始逐个生成所有的排列的方法。

二、快速排序快速排序(Quicksort)是对冒泡排序的一种改进。

它的基本思想是: 通过一趟排序将要排序的数据分割成独立的两部分, 其中一部分的所有数据都比另外一部分的所有数据都要小, 然后再按此方法对这两部分数据分别进行快速排序, 整个排序过程可以递归进行, 以此达到整个数据变成有序序列。

【实验内容】1.全排列递归算法的实现。

2.快速排序分治算法的实现。

【实验结果】1.全排列:快速排序:实验二最长公共子序列、活动安排问题【实验目的】了解动态规划算法设计思想, 运用动态规划算法实现最长公共子序列问题。

了解贪心算法思想, 运用贪心算法设计思想实现活动安排问题。

【实验原理】一、动态规划法解最长公共子序列设序列X=<x1, x2, …, xm>和Y=<y1, y2, …, yn>的一个最长公共子序列Z=<z1, z2, …, zk>, 则:..i.若xm=yn, 则zk=xm=yn且Zk-1是Xm-1和Yn-1的最长公共子序列...ii.若xm≠yn且zk≠x., 则Z是Xm-1和Y的最长公共子序列...iii.若xm≠yn且zk≠y.,则Z是X和Yn-1的最长公共子序列.其中Xm-1=<x1, x2, …, xm-1>, Yn-1=<y1, y2, …, yn-1>, Zk-1=<z1, z2, …, zk-1>。

北邮程序设计实验报告

北邮程序设计实验报告

实验名称:程序设计实验实验时间:2023年X月X日实验地点:北邮计算机实验室一、实验目的1. 熟悉C语言编程环境,掌握基本的程序设计方法。

2. 通过实际编程,提高逻辑思维和问题解决能力。

3. 理解算法设计的重要性,掌握常用的算法设计方法。

二、实验内容本次实验主要分为以下几个部分:1. 编写一个计算两个整数相加的程序。

2. 编写一个计算两个整数相减的程序。

3. 编写一个计算两个整数相乘的程序。

4. 编写一个计算两个整数相除的程序(要求考虑除数为0的情况)。

5. 编写一个判断两个整数是否相等的程序。

三、实验步骤1. 打开C语言编程环境,创建一个新的项目。

2. 编写计算两个整数相加的程序:```c#include <stdio.h>int main() {int a, b, sum;printf("请输入两个整数:\n");scanf("%d %d", &a, &b);sum = a + b;printf("两个整数相加的结果为:%d\n", sum); return 0;}```3. 编写计算两个整数相减的程序:```c#include <stdio.h>int main() {int a, b, sub;printf("请输入两个整数:\n");scanf("%d %d", &a, &b);sub = a - b;printf("两个整数相减的结果为:%d\n", sub); return 0;}```4. 编写计算两个整数相乘的程序:```c#include <stdio.h>int main() {int a, b, mul;printf("请输入两个整数:\n");scanf("%d %d", &a, &b);mul = a b;printf("两个整数相乘的结果为:%d\n", mul);return 0;}```5. 编写计算两个整数相除的程序(考虑除数为0的情况):```c#include <stdio.h>int main() {int a, b, div;printf("请输入两个整数:\n");scanf("%d %d", &a, &b);if (b == 0) {printf("除数不能为0,请重新输入。

算法设计与分析实验报告(模版)

算法设计与分析实验报告(模版)

武汉工程大学计算机科学与工程学院《算法设计与分析》实验报告专业班级实验地点学生学号指导教师学生姓名实验时间实验项目算法基本工具和优化技巧实验类别基本性实验实验目的及要求目的与要求:练习算法基本工具和优化技巧的使用实验内容要点:1、熟悉循环和递归的应用2、熟悉数据结构在算法设计中的应用3、了解优化算法的基本技巧4、掌握优化算法的数学模型成绩评定表类别评分标准分值得分合计上机表现积极出勤、遵守纪律主动完成实验设计任务30分实验报告及时递交、填写规范内容完整、体现收获70分说明:评阅教师:日期:年月日一、狼找兔子问题:一座山周围有n个洞,顺时针编号为0,1,2.,…,n-1。

一只狼从0号洞开始,顺时针方向计数,每当经过第m个洞时,就进洞找兔子。

输入m,n,问兔子有没有幸免的机会?如果有,该藏哪里?代码设计:。

结果:。

二、有52张牌,使他们全部正面朝上,第一轮是从第2张开始,凡是2的倍数位置上的牌翻成正面朝下;第二轮从第3张牌开始,凡是3的倍数位置上的牌,正面朝上的翻成正面朝下,正面朝下的翻成正面朝上;第三轮从第4张开始,凡是4的倍数位置上的牌,正面朝上的翻成正面朝下,正面朝下的翻成正面朝上,以此类推,直到翻的牌超过104张为止。

统计最后有几张正面朝上,以及他们的位置号。

代码设计:。

结果:。

三、A、B、C、D、E 5人为某次竞赛的前5名,他们在名次公布前猜名次。

A说:B得第三名,C得第五名。

B说:D得第二名,E得第四名。

C说:B得第一名,E得第四名。

D说:C得第一名,B得第二名。

E说:D得第二名,A得第三名。

结果每个人都猜对了一半,实际名次是什么呢?代码设计:。

结果:。

北邮数据结构第三次实验-实验报告

北邮数据结构第三次实验-实验报告

数据结构实验报告实验名称:实验三——栈和队列学生姓名:班级:班内序号:学号:日期:1.实验要求1.1 实验目的通过选择下面两个题目之一进行实现,掌握如下内容:➢掌握二叉树基本操作的实现方法➢了解赫夫曼树的思想和相关概念➢学习使用二叉树解决实际问题的能力1.2 实验内容根据二叉树的抽象数据类型的定义,使用二叉链表实现一个二叉树。

二叉树的基本功能:1、二叉树的建立2、前序遍历二叉树3、中序遍历二叉树4、后序遍历二叉树5、按层序遍历二叉树6、求二叉树的深度7、求指定结点到根的路径8、二叉树的销毁9、其他:自定义操作编写测试main()函数测试线性表的正确性2. 程序分析2.1 二叉链表2.2 二叉树的二叉链表存储示意图2.3 关键算法分析2.3.1算法1:void create(Binode<T> *&R, T data[], int i);[1] 算法功能:创建一个二叉树[2] 算法基本思想:通过构造函数创建一个二叉树,构造函数通过调用函数create()创建二叉树,关于函数create()的伪代码:1.定义根指针,输入节点储存的data,若输入“#”,则该节点为空;2.申请一个新节点,判断它的父结点是否不为空,如果不为空在判断其为左或者右孩子,并把地址付给父结点,把data写入。

[3] 算法空间、时间复杂度:O(n)[4] 代码逻辑(可用伪代码描述):if(data[i-1]!=0){R = new Binode<T>;R->data= data[i-1];R->lch = R->rch = NULL;create(R->lch, data,2*i);create(R->rch, data, 2*i+1);}2.3.2算法2:void Destroy(Binode<T> *R);[1] 算法功能:二叉树的销毁[2] 算法基本思想:采用后序遍历的方法,释放节点。

北邮数据结构实验三-哈夫曼树

北邮数据结构实验三-哈夫曼树

数据结构实验报告实验名称:实验三——树学生姓名:班级:班内序号:学号:日期:1 实验目的通过选择下面两个题目之一进行实现,掌握如下内容:➢掌握二叉树基本操作的实现方法➢了解哈夫曼树的思想和相关概念➢学习使用二叉树解决实际问题的能力实验内容:利用二叉树结构实现哈夫曼编/解码器。

基本要求:1、初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个字符的频度,并建立哈夫曼树2、建立编码表(CreateTable):利用已经建好的哈夫曼树进行编码,并将每个字符的编码输出。

3、编码(Encoding):根据编码表对输入的字符串进行编码,并将编码后的字符串输出。

4、译码(Decoding):利用已经建好的哈夫曼树对编码后的字符串进行译码,并输出译码结果。

5、打印(Print):以直观的方式打印哈夫曼树(选作)6、计算输入的字符串编码前和编码后的长度,并进行分析,讨论赫夫曼编码的压缩效果。

(选作)7、可采用二进制编码方式(选作)测试数据:I love data Structure, I love Computer。

I will try my best to study dataStructure.2 程序分析2.1存储结构:三叉树:class Huffman{private:HNode*HTree;//哈夫曼树结点HCode*HCodeTable;//哈夫曼编码表char b[1000];//记录所有输入内容被编码后的结果char c[127];char letter[1000];//输入内容的保存void SelectMin(int &x,int &y,int k);//求最小权重的字符node*count;//计算各个字符出现次数int n;//输入字符的种类(个数)int l;public:Huffman();void CreateHTree();//创建哈夫曼树void CreateCodeTable();//创建哈夫曼编码表void Encode();//编码void Decode();//解码};结点结构为如下所示:三叉树的节点结构:struct HNode//哈夫曼树结点的结构体{ int weight;//结点权值int parent;//双亲指针int lchild;//左孩子指针int rchild;//右孩子指针char data;//字符};示意图为:编码表节点结构:struct HCode//编码表结构体{char data;//字符char code[100];//编码内容};基本结构体记录字符和出现次数:struct node{int num;char data;};2.关键算法分析(1).初始化:伪代码:1.输入需要编译的文本内容2.将输入的内容保存到动态建立的node型数组count中3.统计出现的字符种类的数目,并且保存到private型变量nHuffman::Huffman()//将输入数据保存到Huffman类中{l=0;n=0;count=new node[127];cout<<"请输入需要编译压缩的内容"<<endl;cin.getline(letter,200,'\n');for(int j=0;j<127;j++) //一个号码代表一种字符{count[j].num=0;}while(letter[l]!='\0')//在结束之前,每输入一个字符,则对应字符的数目则自增1 {++count[letter[l]].num;count[letter[l]].data=letter[l];++l;}for(int k=0;k<127;k++) {if(count[k].num>0){n++;}//在某个字符出现此书num不为0时,n自增1,最终n为出现的字符种类数目}其时间复杂度为O(n)(2).创建哈夫曼树(void HuffmanTree::CreateCodeTable(Node *p))算法伪代码:1.创建一个长度为2*n-1的三叉链表2.将存储字符及其权值的链表中的字符逐个写入三叉链表的前n个结点的data域,并将对应结点的孩子域和双亲域赋为空3.从三叉链表的第n个结点开始,3.1从存储字符及其权值的链表中取出两个权值最小的结点x,y,记录其下标x,y。

《算法设计与分析》实验报告模板 (1)

《算法设计与分析》实验报告模板 (1)

《算法设计与分析》实验报告
学号:姓名:
实验一分治法求解众数问题
一、实验目的
1.掌握分治法的设计思想并能熟练应用;
2.理解分治与递归的关系。

二、实验题目
在一个序列中出现次数最多的元素称为众数,根据分治法的思想设计算法寻找众数。

三、实验程序
四、程序运行结果
实验二动态规划法求解单源最短路径问题
一、实验目的
1.深刻掌握动态规划法的设计思想;
2.熟练应用以上算法思想求解相关问题。

二、实验题目
设有一个带权有向连通图,可以把顶点集划分成多个互不相交的子集,使得任一条边的两个顶点分属不同子集,称该图为多段图。

采用动态规划法求解多段图从源点到终点的最小代价路径。

三、实验程序
四、程序运行结果
实验三贪心法求解单源点最短路径问题
一、实验目的
1.掌握贪心法的设计思想;
2.分析比较同一个问题采用不同算法设计思想求解的结果。

二、实验题目
设有一个带权有向连通图,可以把顶点集划分成多个互不相交的子集,使得任一条边的两个顶点分属不同子集,称该图为多段图。

采用贪心法求解多段图从源点到终点的最小代价路径。

三、实验程序
四、程序运行结果
实验四回溯法求解0/1背包问题
一、实验目的
1.掌握回溯法的设计思想;
2.掌握解空间树的构造方法,以及在求解过程中如何存储求解路径;
二、实验题目
给定n种物品和一个容量为C的背包,选择若干种物品(物品不可分割),使得装入背包中物品的总价值最大。

采用回溯法求解该问题。

三、实验程序
四、程序运行结果。

《算法设计与分析》课程实验报告

《算法设计与分析》课程实验报告

《算法设计与分析》课程实验报告实验序号:实验项目名称:随机化算法一、实验题目1.N后问题问题描述:在n*n格的棋盘上放置彼此不受攻击的n个皇后,任何两个皇后不放在同一行同一列,同一斜线上,问有多少种放法。

2.主元素问题问题描述:设A是含有n个元素的数组,如果元素x在A中出现的次数大于n/2,则称x是A的主元素。

给出一个算法,判断A中是否存在主元素。

二、实验目的(1)通过N后问题的实现,体会拉斯维加斯随机算法的随机特点:运行次数随机但有界,找到的解一定为正确解。

但某次运行可能找不到解。

(2)通过实现主元素的不同算法,了解蒙特卡罗算法的随机特性:对于偏真的蒙特卡罗算法,找到为真的解一定是正确解;但非真的解以高概率给出解的正确率------即算法找到的非真解以小概率出现错误。

同时体会确定性算法与随机化算法的差异及各自的优缺点。

(3)通过跳跃表的实现,体会算法设计的运用的广泛性,算法设计的思想及技巧不拘泥独立问题的解决,而在任何需要计算机解决的问题中,都能通过算法设计的技巧(无论是确定性还是随机化算法)来灵巧地解决问题。

此实验表明,通过算法设计技巧与数据组织的有机结合,能够设计出高效的数据结构。

三、实验要求(1)N后问题分别以纯拉斯维加斯算法及拉斯维加斯算法+回溯法混合实现。

要求对同一组测试数据,完成如下任务a.输出纯拉斯维加斯算法找到解的运行次数及运行时间。

b.输出混合算法的stopVegas值及运行时间c.比较a、b的结果并分析N后问题的适用情况。

(2)主元素问题,要求对同一组测试数据,完成如下任务:a.若元素可以比较大小,请实现O(n )的确定性算法,并输出其运行时间。

b.(选做题)若元素不可以比较大小,只能比较相同否,请实现O(n) 确性算法,并输出其运行时间。

c.实现蒙特卡罗算法,并输出其运行次数及时间。

d.比较确定性算法与蒙特卡罗算法的性能,分析每种方法的优缺点。

(3)参照教材实现跳跃表(有序)及基本操作:插入一个结点,删除一个结点。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

算法设计与分析第三章程序作业源程序代码1.最长公共子序列#include<stdio.h>#include<stdlib.h>#define N 1000int e[N][N],f[N][N];void LCSLength(int m,int n,char *x,char *y,int c[][N],int b[][N])//构造数组b[i][j]{int i,j;for (i=1; i<=m;i++)c[i][0]=0; //初始化, Y[j]为空时for (i=1;i<=n;i++)c[0][i]=0; //初始化,X[i]为空时for (i=1;i<=m;i++) //两重循环,自下而上,// 计算子问题{X(i), Y(j)}for (j=1;j<=n;j++){if(x[i]==y[j]){ //情况1c[i][j]=c[i-1][j-1]+1;b[i][j]=1;}else if(c[i-1][j]>=c[i][j-1]){ //情况2c[i][j]=c[i-1][j];b[i][j]=2;}else //情况3{c[i][j]=c[i][j-1];b[i][j]=3;}}}void LCS(int i,int j,char *x,int b[][N]){if (i==0||j==0)return;if (b[i][j]==1){LCS(i-1,j-1,x,b);printf("%c",x[i]);/*第1种情况下,X(i)和Y(j)的最长公共子序列由X(i-1)和Y(j-1)的解LCS(i-1, j-1, x, b),加上位于最后的X[i]组成*/}else if(b[i][j]==2)LCS(i-1,j,x,b);elseLCS(i,j-1,x,b); //其它2种情况下,原问题解等于子问题解}main(){char A[N],B[N],C[N],D[N];int a=1,b=1,c=1,d=1;char ch;int i;FILE * fp;if((fp=fopen("最长公共子序列输入数据.txt","r"))==NULL)//打开文件失败printf("Can't open file ");else{//读取文件内容ch=fgetc(fp);ch=fgetc(fp);ch=fgetc(fp);ch=fgetc(fp);ch=fgetc(fp);while(ch!='B'&&ch!=EOF) {A[a]=ch;a++;ch=fgetc(fp);while(ch=='\n')ch=fgetc(fp);}a--;ch=fgetc(fp);ch=fgetc(fp);ch=fgetc(fp);ch=fgetc(fp);while(ch!='C'&&ch!=EOF) {B[b]=ch;b++;ch=fgetc(fp);while(ch=='\n')ch=fgetc(fp);}b--;ch=fgetc(fp);ch=fgetc(fp);ch=fgetc(fp);ch=fgetc(fp);while(ch!='D'&&ch!=EOF) {C[c]=ch;c++;ch=fgetc(fp);while(ch=='\n')ch=fgetc(fp);}c--;ch=fgetc(fp);ch=fgetc(fp);ch=fgetc(fp);ch=fgetc(fp);while(ch!=EOF){D[d]=ch;d++;ch=fgetc(fp);while(ch=='\n')ch=fgetc(fp);}d--;}fclose(fp);printf("文件读取完成\n");/* for(i=0;i<=a;i++)printf("%c",A[i]);printf("\n");for(i=0;i<=b;i++)printf("%c",B[i]);printf("\n");for(i=0;i<=c;i++)printf("%c",C[i]);printf("\n");for(i=0;i<=d;i++)printf("%c",D[i]);printf("\n"); */printf("\n\n\nA和B的最长公共子序列为:\n");LCSLength(a,b,A,B,e,f);LCS(a,b,A,f);printf("\n\n\nC和D的最长公共子序列为:\n");LCSLength(c,d,C,D,e,f);LCS(c,d,C,f);printf("\n\n\nA和D的最长公共子序列为:\n");LCSLength(a,d,A,D,e,f);LCS(a,d,A,f);system("pause");return 0;}2.最大子段和#include<stdio.h>#include<stdlib.h>#define N 400void MaxSum(int n,int *a){int sum=0,b=0;int i,x1=0,y1=0,x=0,y=0;for(i=1;i<=n;i++){if (b>0){b+=a[i];y1=i;}else{b=a[i];x1=i;}if(b>sum){sum=b;x=x1;y=y1;}}printf("\n该序列的最大子段和的位置为从第%d个到第%d个",x+1,y+1);printf("\n该序列的和最大子段为:\n");for(i=x;i<=y;i++)printf("%d ",a[i]);printf("\n它们的和为%d \n",sum);}main(){int A[N],B[N];int a=0,b=0;int i;FILE *fp1,*fp2;if((fp1=fopen("最大子段和输入数据-序列1.txt","r"))==NULL)//打开文件失败printf("Can't open file1 ");else //读取文件内容for(i=0;!feof(fp1);i++)fscanf(fp1,"%d\n",&A[i]);a=i-1;}if((fp2=fopen("最大子段和输入数据-序列2.txt","r"))==NULL)//打开文件失败printf("Can't open file2 ");else{for(i=0;!feof(fp2);i++)fscanf(fp2,"%d\n",&B[i]);b=i-1;}fclose(fp1);fclose(fp1);printf("文件读取成功!!!\n\n\n");printf("对于最大子段和输入数据-序列1 ");MaxSum(a,A);//计算最大子段和printf("\n\n对于最大子段和输入数据-序列2 ");MaxSum(b,B);// for(i=0;i<=b;i++)// printf("%d ",B[i]);system("pause");return 0;}3.凸多边形最优三角剖分#include<stdio.h>#include<stdlib.h>#include<math.h>#define N 30#define EARTH_RADIUS 6378.137struct Base{//基站结构体int ENODEBID;//基站标识float LONGITUDE;//基站经度float LATITUDE;//基站纬度int NUM;//基站k-dist距离};void readfile(struct Base * base,int n) //读取文件函数{FILE * fp;int i=0;if(n==21)fp=fopen("21个基站凸多边形数据.csv","rb");elsefp=fopen("29个基站凸多边形数据.csv","rb");if(fp==NULL)//打开文件失败printf("Can't open file ");else{while(EOF!=fscanf(fp,"%d,%f,%f,%d",&base[i].ENODEBID,&base[i].LO NGITUDE,&base[i].LATITUDE,&base[i].NUM)){//将数据读入结构体数组i++;//printf("%d\n",i);}// printf("文件读入成功!!!\n\n\n");fclose(fp);}float rad(float LatOrLon){return LatOrLon * 3.14/180.0;}float distance(struct Base * base,int a,int b)//求两个基站间的距离{float s;float radLat1,radLat2,radlng1,radlng2;radLat1 = rad(base[a].LATITUDE);radLat2 = rad(base[b].LATITUDE);radlng1 = rad(base[a].LONGITUDE);radlng2 = rad(base[b].LONGITUDE);//利用正弦余弦公式求距离if(radLat1==radLat2&&radlng1==radlng2)s=0;elses=acos(cos(radLat1)*cos(radLat2)*cos(radlng1-radlng2)+sin(radLat1)*s in(radLat2));s = s * EARTH_RADIUS;s=round(s*1000);}return s;}float weight(struct Base * base,int a,int b,int c){float s,s1,s2,s3;s1=distance(base,a,b);s2=distance(base,b,c);s3=distance(base,a,c);//s=distance(base,a,b)+distance(base,b,c)+distance(base,a,c);s=s1+s2+s3;return s;}float MinWeightTriangulation(struct Base * base,int n,float t[][N],int s[][N]){int i,j,r,k;float u=0;for(i=1;i<=n;i++)t[i][i]=0;for(r=2;r<=n;r++) //r为当前计算的链长(子问题规模)for(i=1;i<=n-r+1;i++)//n-r+1为最后一个r链的前边界{j=i+r-1;//计算前边界为r,链长为r的链的后边界t[i][j]=t[i+1][j]+weight(base,i-1,i,j);//将链ij划分为A(i) * ( A[i+1:j] )这里实际上就是k=is[i][j]=i;for (k=i+1;k<i+r-1;k++) //将链ij划分为( A[i:k] )* (A[k+1:j]){u=t[i][k]+t[k+1][j]+weight(base,i-1,k,j);if(u<t[i][j]){t[i][j]=u;s[i][j]=k;}}}return t[1][n];}void Traceback(int i,int j,int s[][N]){if(i==j)return;Traceback(i,s[i][j],s);Traceback(s[i][j]+1,j,s);printf("三角剖分顶点:V%d , V%d , V%d\n",i-1,j,s[i][j]); }main(){int i;float t[N][N];int s[N][N];struct Base base21[N];//结构体(N宏定义)struct Base base29[N];//结构体(N宏定义)readfile(base21,21);//将数据从文件中读到结构体中readfile(base29,29);//将数据从文件中读到结构体中printf("文件读入成功!!!\n\n\n");// for(i=0;i<=28;i++)//printf("%6d %.3f %.5f %d\n",base29[i].ENODEBID,base29[i].LONGITU DE,base29[i].LATITUDE,base29[i].NUM);printf("凸21多边形的最优三角剖分值为%f",MinWeightTriangulation(base21,20,t,s));printf("最优三角剖分结构为:\n");Traceback(1,20,s); //s[i][j]记录了Vi-1和Vj构成三角形的第3个顶点的位置printf("凸29多边形的最优三角剖分值为%f",MinWeightTriangulation(base29,28,t,s));printf("最优三角剖分结构为:\n");Traceback(1,28,s); //s[i][j]记录了Vi-1和Vj构成三角形的第3个顶点的位置system("pause");return 0;}4.01背包问题#include<stdio.h>#include<stdlib.h>#define N 100struct Goods{int weight;//物品重量int value;//物品价值};int knapsack(struct Goods *goods,int bag,int number,int p[][2],int head[]){int left=0,right=0,next=1,i,j,k,m,y;p[0][0]=0;p[0][1]=0;head[number+1]=0;head[number]=1;for(i=number;i>=1;i--){k=left;for(j=left;j<=right&&p[j][0]+goods[i-1].weight<=bag;j++){ y=p[j][0]+goods[i-1].weight;m=p[j][1]+goods[i-1].value;while(k<=right&&p[k][0]<y){p[next][0]=p[k][0];p[next][1]=p[k][1];next++;k++;}if(k<=right&&p[k][0]==y){if(m<p[k][1]){m=p[k][1];}k++;}if(m>p[next-1][1]){p[next][0]=y;p[next][1]=m;next++;}while(k<=right&&p[k][1]<=p[next-1][1]){k++;}}while(k<=right){p[next][0]=p[k][0];p[next][1]=p[k][1];next++;k++;}left=right+1;right=next-1;head[i-1]=next;}return next;}void traceback(struct Goods *goods,int number,int head[],int p[][2],int x[]){int j=p[head[0]-1][0],m=p[head[0]-1][1];int i,k,a;for(i=1;i<=number;i++){x[i]=0;a=1;// for(k=3450;k<=head[i]-1&&a==1;k++)for(k=head[i+1];k<=head[i]-1&&a==1;k++){if(p[k][0]+goods[i-1].weight==j&&p[k][1]+goods[i-1].value==m){x[i]=1;j=p[k][0];m=p[k][1];a=0;}}}}main(){int bag1,bag2;//背包容量int number1,number2;//物品数目int i,n;int p[20000][2];int h[N],x[N];struct Goods goods1[N],goods2[N];FILE *fp;char ch='0';if((fp=fopen("附件4.背包问题输入数据.txt","r"))==NULL)//打开文件失败printf("Can't open file ");else //读入背包和物品信息{fseek(fp,18,SEEK_CUR);fscanf(fp,"%d",&bag1);//背包1容量fseek(fp,18,SEEK_CUR);ch='0';for(i=0;ch!='\n';i++){fscanf(fp,"%d",&goods1[i].weight);//物品重量}number1=i;ch='0';fseek(fp,14,SEEK_CUR);for(i=0;ch!='\n'&&ch!=EOF;i++){fscanf(fp,"%d",&goods1[i].value);//物品价值ch=fgetc(fp);}if(number1!=i){printf("读取数据出错,程序将退出!\n");system("pause");}fseek(fp,22,SEEK_CUR);fscanf(fp,"%d",&bag2);//背包1容量fseek(fp,18,SEEK_CUR);ch='0';for(i=0;ch!='\n';i++){fscanf(fp,"%d",&goods2[i].weight);//物品重量}number2=i;ch='0';fseek(fp,14,SEEK_CUR);for(i=0;ch!='\n'&&ch!=EOF;i++){fscanf(fp,"%d",&goods2[i].value);//物品价值ch=fgetc(fp);}if(number2!=i){printf("读取数据出错,程序将退出!\n");system("pause");}}printf("文件读取成功!!!\n");/*打印文件的信息*/printf("\n\n第一组背包数据:\n");printf("背包容量:%d 物品数量:%d\n物品重量:\n",bag1,number1);for(i=0;i<number1;i++)printf("%d ",goods1[i].weight);printf("\n物品价值:\n");for(i=0;i<number1;i++)printf("%d ",goods1[i].value);printf("\n\n第二组背包数据:\n");printf("背包容量:%d 物品数量:%d\n物品重量:\n",bag2,number2);for(i=0;i<number2;i++)printf("%d ",goods2[i].weight);printf("\n物品价值:\n");for(i=0;i<number2;i++)printf("%d ",goods2[i].value);n=knapsack(goods1,bag1,number1,p,h);traceback(goods1,number1,h,p,x); //确定放入的物品//打印结果printf("\n\n第一组:\n背包重量为:%d 背包价值为:%d\n",p[n-1][0],p[n-1][1]);printf("放入的物品为:\n");for(i=1;i<number1;i++)if(x[i]==1)printf("物品%-2d 重量%-2d 价值%d\n",i,goods1[i-1].weight,goods1[i-1].value);//第二组数据n=knapsack(goods2,bag2,number2,p,h);traceback(goods2,number2,h,p,x);printf("\n\n第二组:\n背包重量为:%d 背包价值为:%d\n",p[n-1][0],p[n-1][1]);printf("放入的物品为:\n");for(i=1;i<number2;i++)if(x[i]==1)printf("物品%-2d 重量%-2d 价值%d\n",i,goods2[i-1].weight,goods2[i-1].value);system("pause");return 0;}运行结果1.最长公共子序列2.最大子段和3.凸多边形最优三角剖分4.01背包问题。

相关文档
最新文档