实验报告题目
实验一递归与分治策略
一、实验目的
1.加深学生对分治法算法设计方法的基本思想、基本步骤、基本方法的理解与掌握;
2.提高学生利用课堂所学知识解决实际问题的能力;
3.提高学生综合应用所学知识解决实际问题的能力。
二、实验内容
设计一个递归和分治算法,找出数组的最大元素,找出x在数组A中出现的次数。
三、实验要求
(1)用分治法求解…问题;
(2)再选择自己熟悉的其它方法求解本问题;
(3)上机实现所设计的所有算法;
四、实验过程设计(算法设计过程)
1.设计一个递归算法,找出数组的最大元素。
2.设计一个分治算法,找出x在数组A中出现的次数。
3.写一个主函数,调用上述算法。
五、实验结果分析
(分析时空复杂性,设计测试用例及测试结果)
时间复杂性:最好情况下,O(n)
最坏情况下:O(nlog(n)
空间复杂性分析:O(n)
六、实验体会
通过写递归与分治策略实验,更加清楚的知道它的运行机理,分治法解题的一般步骤:(1)分解,将要解决的问题划分成若干规模较小的同类问题;(2)求解,当子问题划分得足够小时,用较简单的方法解决;(3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解。做实验重在动手动脑,还是要多写写实验,才是硬道理。
七、附录:(源代码)
#include"stdio.h"
#define ElemType int
int count(ElemType a[],int i,int j,ElemType x)
{
int k=0,mid; //k用来计数,记录数组中x出现的次数if(i==j)
{
if(a[i]==x) k++;
return k;
}
else
{
mid=(i+j)/2;
k+=count(a,i,mid,x);
k+=count(a,mid+1,j,x);
}
return k;
}
ElemType Maxitem(ElemType a[],int n)
{
ElemType max=a[n-1],j;
if(n==1)
{
max=a[n-1];
return max;
}
else
{
j=Maxitem(a,n-1);
if(j>max) max=j;
return max;
}
}
void main(void)
{
ElemType a[]={1,5,2,7,3,7,4,8,9,5,4,544,2,4,123};
ElemType b;
ElemType x;
int n;
b=Maxitem(a,15);
printf("数组的最大元素为%d\n",b);
printf("输入想要计数的数组元素:\n");
scanf("%d",&x);
n=count(a,0,14,x);
printf("%d在数组中出现的次数为%d次\n",x,n);
}
实验二动态规划——求解最优问题
一、实验目的
1.加深学生对动态规划算法设计方法的基本思想、基本步骤、基本方法的理解与掌握;
2.提高学生利用课堂所学知识解决实际问题的能力;
3.提高学生综合应用所学知识解决实际问题的能力。
二.实验内容
根据实验目的要求和实验条件,由学生运用所学知识,自行选择最优问题,自己设计算法,自行编程实现、自行对实验结果进行分析,自行完成实验项目报告的撰写等。在教师的指导下,最大限度发挥学生资助学习的积极性,为后续专业课的学习打下坚实基础。
三.实验要求
(1)用动态规划思想求解最优问题;
(2)再选择自己熟悉的程序设计语言实现所有算法;
(3)分析所设计的算法的时间/空间复杂性。
四.实验过程设计(算法设计过程)
实验3.3。先在a[],b[]数组中选a[0]和b[0]开始,然后分别计算在以a[0]和b[0]开始的总的时间,再比较哪个最短。
五.实验结果分析
六.实验体会
始终觉得用代码写着比用笔直接计算要难点,不过代码解决的事一类问题,只需要输数据就可以。所以还是代码好,不过要有好的逻辑思维和方法,才能写出好的
七.附录:(源代码)
#include "stdio.h"
#include "iostream.h"
#include "string.h"
void main()
{
void sf(int a[],int b[],int n);
int a[100],b[100],n,i;
printf("请输入需要完成的作业数量:");
scanf("%d",&n);
printf("请输入A组机器完成作业对应的时间:");
for(i=0;i printf("请输入B组机器完成作业对应的时间:"); for(i=0;i f(a,b,n); } void f(int a[],int b[],int n) { int max(int a,int b); int i,j,d,low,high,k,A,B,v[100]; for(i=0;i { for(j=0;j { if(a[i] { d=a[i]; a[i]=a[j]; a[j]=d; d=b[i]; b[i]=b[j]; b[j]=d; } } } for(i=0;i { low=i; high=i; while(a[i]==a[i+1]) { i++; high=i; } if(low!=high) { for(k=low;k<=high;k++) { for(j=k;j<=high;j++) { if(b[k] { d=b[k]; b[k]=b[j]; b[j]=d; } } } } } for(i=0;i { A=0; B=0; j=0; while(j<=i) { A=A+a[j]; j++; } while(j { B=B+b[j]; j++; } v[i]=max(A,B); } i=1; d=v[0]; while(i { if(v[i] { d=v[i]; } i++; } printf("最短作业时间为:%d\n",d); } int max(int a,int b) { if(a>b) { return a; } else{ return b; } } 实验三贪心算法——“0/1背包”及“有限期作业调度” 一、实验目的 1.进一步理解算法设计的基本步骤及各步的主要内容、基本要求 2.加深对贪婪法算法设计方法的理解与应用 3.掌握将算法转化为计算机上机程序的方法 4.培养学生应用所学知识解决实际问题的能力。 二.实验内容 (1)给定n种物品和一个背包。物品I的重量是w i,其价值为p i,背包的容量为M。应如何选择装入背包的物品(每件物品可以全装也可以只装一部分),使得装入背包中物品的总价值最大? (2)给定n个作业j1, j2,…, j n。对每个作业j i,有一个与之联系的限期d i>0和收益p i≥0,d i,p i均为整数,1≤I≤n。对作业j i,只有在限期d i内完成,才能得到收益p i。假定只有一台处理机为这批服务业服务,处理机每次只能处理一个作业,并且完成一作业需一个单位时间。所谓一个可行解,是这批作业的一个子集J,J中每一作业均能在限期d i内完成。调度的总收益是子集J中各作业收益之和。具有最大收益的的可行解和为最优解。如何求其最优解? 三.实验要求 (1)设计用贪婪法求解“背包问题”及“带有限期的计算机作业调度问题”的算法; (2)上机实现所设计的算法; (3)分析所设计的算法的时间/空间复杂性。 四.实验过程设计(算法设计过程) 后面人的等到时间等于前面人的服务时间,要总的等待时间最短,就要前面的服务时间最短,就需要先让服务时间段的人先进行服务。 1.先按原来的顺序服务时间服务,得到一个等待时间 2.升序排列后,得到一个等待时间 五.结果分析 六.实验体会 后面人的等到时间等于前面人的服务时间,要总的等待时间最短,就要前面的服务时间最短,就需要先让服务时间段的人先进行服务。这是总的实验思路。贪心算法就是要尽可能的提高效率,得到想要的效益。 七.附录(源代码) #include "stdio.h" #include "iostream.h" #include "string.h" main() { int i,j,n,a[100],d=0,k=0; printf("请输入顾客的总人数:"); scanf("%d",&n); printf("依次输入每个顾客的服务时间:"); for(i=0;i for(i=0;i { d=0; for(int j=0;j { d=d+a[j];//第j个人的等待时间 } k=k+d;//总的等待时间 } printf("此时等待的总时间为:%d\n",k); for(i=0;i { for(int j=i;j { if(a[i]>a[j]) { d=a[i]; a[i]=a[j]; a[j]=d; } } } printf("按升序排列后的数组为:"); for(i=0;i k=0; for(i=0;i { d=0; for(int j=0;j { d=d+a[j]; } k=k+d; } printf("\n此时等待的总时间为:%d\n",k); } 实验四回溯法——“N皇后”问题 一、实验目的 1.掌握能用回溯法求解的问题应满足的条件; 2.加深对回溯法算法设计方法的理解与应用; 3.锻炼学生对程序跟踪调试能力; 4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。 二.实验内容 由N2个方块排成N行N列的正方形,称为N元棋盘,在N元棋盘上放置N个皇后,如果某两个皇后位于N元棋盘的同一行或同一列或同一斜线(斜率为±1)上,则称它们在互相攻击,试设计算法找出使N个皇后互不攻击的所有布局。 三.实验要求 (1)用回溯法算法设计方法求解N元皇后问题 (2)找出N皇后问题的互不攻击的所有解 (3)皇后数N由键盘动态输入 (4)上机实现所设计的算法; (5)分析所设计的算法的时间/空间复杂性。 四.实验过程设计(算法设计过程) (1)分析N皇后问题的约束条件,并将其显示化,选择存储结构建立相应的数学模型; (2)根据所建立的数学模型,设计求解该问题的粗略算法; (3)对所设计的粗略算法求精,得具体算法; (4)在C/C++/VC++下实现所设计的算法; (5)分屏显示结果; (6)分析运行结果的正确性; (7)进行算法效率分析; (8)课后写出实验报告。 五.实验结果和分析 六.实验体会 解n后问题主要在于可行解,一个一个的试,(t)能走通就往(t+1)下走,走不通就倒回去(t-1)换条走,再不行再回走。就要不停的尝试,不停的回溯,直到找全可行解,或者一个也没有就停止。还有重要的事约束条件,两个皇后不能在同行同列或者斜线上。 七.附录(源代码) #include "stdio.h" #include "iostream.h" #include "string.h" #include int n; int x[100]; int sum=0; int k=1; int nQueen(int nn) { n=nn; void backtrack(int t); for(int i=0;i<=n;i++) { x[i]=0; } backtrack(1); return sum; } int place(int k) { 2012 -2013第一学期 for(int j=1;j { if((abs(k-j)==abs(x[j]-x[k]))||(x[j]==x[k])) { return 0; } } return 1; } void backtrack(int t) { if(t>n) { printf("第"%d"个解的答案为:",k); k++; sum++; for(int i=1;i<=n;i++)printf("%d",x[i]); } else { for(int i=1;i<=n;i++) { x[t]=i; if(place(t)) { backtrack(t+1); } } } } main() { int nn; printf("输入n皇后n值:"); scanf("%d %d",&n,&n); nQueen(nn); } 2012 -2013第一学期 算法分析与设计实验报告 学生姓名:系别:专业与班号:学号: 实验名称:Strassen’s 矩阵乘法和最近点对算法 实验目的 1、理解“分治法”算法设计思想及其实现步骤 2、掌握分治算法效率递归分析方法 3、掌握主方式求解递归式方法 实验内容及要求 1、利用计算机程序设计语言,实现教材第28.2 章介绍的“Strassen’s 矩阵乘法算法”,自主生成两个8×8 的矩阵,检验算法的正确性并输出算法结果。 2、比较 Strassen’s 矩阵乘法算法和数学定义的矩阵乘法算法效率之间的区别,并用直观的表达方式把两种不同矩阵乘法的效率随矩阵维数的变化趋势。 3、利用计算机程序设计语言,实现教材第33.4 章介绍的“最近点对算法”,在拟定的二维空间点集上检验算法的正确性并输出算法结果。 实验原理 1.Strassen’s矩阵乘法简介 Strassen’s算法是将矩阵分成了如图所示的均等的四块。分后的每一块儿任然还是方阵。 所以可以由大问题分解成若干子问题进行解决。为了能使子问题能够返回到原始问题。 Strassen‘s算法提出了如下的计算公式,可以用矩阵的子矩阵计算出S1-S7,然后又由S1-S7合成原始矩阵。而S1-S7的计算又是方阵的乘法。由此使用分治算法便可以解决问题。 2.最近点对问题(Closest Pair Problems)算法简介 首先这个问题也是采用了分治的思想,将空间内的距离分成三类,分界线左边的点之间的距离,分界线右边的点之间的距离,还有分界线两边距离为D 的区域内的两点间距离。 算法具体代码 1.矩阵相乘问题 // Strassen.cpp : 定义控制台应用程序的入口点。 // //******************************************************************************** #include "stdafx.h" #include "stdlib.h" #define AM Copy(A,0,0,A.v/2) #define BM Copy(A,A.v/2,0,A.v/2) #define CM Copy(A,0,A.v/2,A.v/2) #define DM Copy(A,A.v/2,A.v/2,A.v/2) #define EM Copy(B,0,0,B.v/2) #define FM Copy(B,B.v/2,0,B.v/2) #define GM Copy(B,0,B.v/2,B.v/2) #define HM Copy(B,B.v/2,B.v/2,B.v/2) #define V 2 //******************************************************************************** //矩阵结构 typedef struct matrix { int v; int x[16][16]; }Matrix; //******************************************************************************** //输入输出文件 FILE *fout; FILE *fin; //******************************************************************************** //矩阵打印(文件) void fPrint(Matrix A) { for(int j=0;j 《算法设计与分析》实验报告实验三回溯法 3.迷宫问题 一天Luna在森林里探险的时候不小心走入了一个迷宫,迷宫可以看成是由n * n的格点组成,每个格点只有2种状态,. 和#,前者表示可以通行后者表示不能通行。同时当Luna处在某个格点时,她只能移动到东南西北(或者说上下左右)四个方向之一的相邻格点上,Luna想要从点A走到点B(不能走出迷宫)。如果起点或者终点有一个不能通行(为#),则看成无法办到。 [输入] 第1行是测试数据的组数k,后面跟着k组输入。 每组测试数据的第1行是一个正整数n (1 <= n <= 100),表示迷宫的规模是n * n 的。 接下来是一个n * n的矩阵,矩阵中的元素为. 或者#。 再接下来一行是4个整数ha, la, hb, lb,描述A处在第ha行, 第la列,B处在第hb 行, 第lb列。注意到ha, la, hb, lb全部是从0开始计数的。 1.八皇后问题 1.1解题思路 八皇后问题的解法,很简单的解法。通过回溯实现枚举。 对于当前行,尝试是否可在当前列放置皇后,然后进入下一行的尝试,同时尝试完毕以后,要将当前行回复(回溯),来进行下一次尝试。 到达最后一行的时候,即递归结束条件,打印结果即可。 1.2程序运行情况 1.3所有的皇后解 见附录。(毕竟92个解...) 1.4程序源码(含注释) 2. 24点问题 2.1 解题思路 这题虽然使用dfs很简单,但是有一点思维在里面。我很惭愧,自己没有想出来怎么如意的独立AC此题。 遇到的最大的问题——如何插入括号?枚举插入、和运算符一同排列都不靠谱。解决方法是:用同等的办法转化。每一次从待组合的是数字中,任取两个数,随机用运算符计算完毕后,再放回去。下一次计算,再次重复这个过程,可以等价为有括号的运算方式了。 遇到第二个问题——如何实现这种“任取两个数”的选择方式。这里就直接体现出了我个人能力的不足。居然没想到。尝试使用STL的set,但是没成功。这里借鉴了网上的AC 思路,我感到自己思维太僵硬。解决方法是——对于当前的运算状态中,用两个循环实现枚举两个数,计算为完毕以后,结果覆盖在数组序号小的那个数的位置,再将第二个数与最后一个数字交换即可进入下一个状态。回溯的时候,只需要回复小序号的数字的位置的值,以及再一次swap即可。(因为第二个数字只是swap却没有改变过内容)。 一个细节问题,就是加法和乘法是没有顺序的,减法和除法是有顺序的,以及除法要考虑0异常。一共是6次枚举即可。 2.2 测试样例 5 5 5 1 ans is YES 1 1 4 2 ans is :NO 2.3 程序运行情况 样例一: 实验一递归1.1实验目的 1)掌握递归算法的概念,理解递归算法的思想 2)掌握递归函数的写法,熟练运用递归函数 3)正确分析递归算法的时空复杂度 1.2 实验内容 1)编写程序递归地实现阶乘函数; 2)编写程序递归地实现Fibonacci数列; 3)编写程序递归实现整数划分问题 1.3 实验步骤 1)写出阶乘函数的定义公式 n!=1 n=0 n n?1! n>0 2)创建一个java程序,递归实现阶乘函数public static int factorial(int n) { if(n==0) return 1; return n*factorial(n-1); } 3)写出Fibonacci数列的定义公式 F n=1 n=0,1 F n?1+F n?2 n>1 4)创建一个java程序,递归实现Fibonacci数列public static int fibonacci(int n) { if(n<=1) return 1; return fibonacci(n-1)+fibonacci(n-2); } 5)分析并写出整数划分的递归公式 q n,m=1 n=1,m=1 q n,n n public static int q(int n,int m) { if((n<1)||(m<1)) return 0; if((n==1)||(m==1)) return 1; if(n 实验一分治与递归(4学时) 一、实验目的与要求 1、熟悉C/C++语言的集成开发环境; 2、通过本实验加深对递归过程的理解 二、实验内容 掌握递归算法的概念和基本思想,分析并掌握“整数划分”问题的递归算法。 三、实验题 任意输入一个整数,输出结果能够用递归方法实现整数的划分。 四、程序代码 五、实验结果 首先按照提示输入数字: 按回车键,得到此数划分的个数: 此时您可以接着计算另一个数的划分个数: 若要退出,请输入一个小于等于零的数: 六、结果分析及程序功能 经过和其它同学的实验数据对比,初步认定此程序基本正确,然而不足之处是只能得到划分的个数,而不能列出每个划分的详细情况。 一、实验目的与要求 1、掌握棋盘覆盖问题的算法; 2、初步掌握分治算法 二、实验题 盘覆盖问题:在一个2k×2k个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。 三、程序代码 四、实验结果 按照提示输入特殊方格的行号和列号(起始行列号为0): 按回车键,得到一个矩阵,数字相同区域为一个L型骨牌覆盖: 五、结果分析及程序功能 得到的16*16棋盘覆盖结果正确,此程序的不足之处:只能设定特殊方格的行列号,而不能设定棋盘的大小。 实验二动态规划算法(4学时) 一、实验目的与要求 1、熟悉最长公共子序列问题的算法; 2、初步掌握动态规划算法; 二、实验题 若给定序列X={x1,x2,…,xm},则另一序列Z={z1,z2,…,zk},是X的子序列是指存在一个严格递增下标序列{i1,i2,…,ik}使得对于所有j=1,2,…,k有:zj=xij。例如,序列Z={B,C,D,B}是序列X={A,B,C,B,D,A,B}的子序列,相应的递增下标序列为{2,3,5,7}。给定2个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。 三、实验程序 本科实验报告 课程名称:算法设计与分析 实验项目:递归与分治算法 实验地点:计算机系实验楼110 专业班级:物联网1601 学号:2016002105 学生姓名:俞梦真 指导教师:郝晓丽 2018年05月04 日 实验一递归与分治算法 1.1 实验目的与要求 1.进一步熟悉C/C++语言的集成开发环境; 2.通过本实验加深对递归与分治策略的理解和运用。 1.2 实验课时 2学时 1.3 实验原理 分治(Divide-and-Conquer)的思想:一个规模为n的复杂问题的求解,可以划分成若干个规模小于n的子问题,再将子问题的解合并成原问题的解。 需要注意的是,分治法使用递归的思想。划分后的每一个子问题与原问题的性质相同,可用相同的求解方法。最后,当子问题规模足够小时,可以直接求解,然后逆求原问题的解。 1.4 实验题目 1.上机题目:格雷码构造问题 Gray码是一个长度为2n的序列。序列无相同元素,每个元素都是长度为n的串,相邻元素恰好只有一位不同。试设计一个算法对任意n构造相应的Gray码(分治、减治、变治皆可)。 对于给定的正整数n,格雷码为满足如下条件的一个编码序列。 (1)序列由2n个编码组成,每个编码都是长度为n的二进制位串。 (2)序列中无相同的编码。 (3)序列中位置相邻的两个编码恰有一位不同。 2.设计思想: 根据格雷码的性质,找到他的规律,可发现,1位是0 1。两位是00 01 11 10。三位是000 001 011 010 110 111 101 100。n位是前n-1位的2倍个。N-1个位前面加0,N-2为倒转再前面再加1。 3.代码设计: 算法设计与分析实验报告棋盘覆盖问题贵州大学计算机科学与技术学院 计算机科学与技术系上机实验报告课程名称:算法设计与分析班级:信计101班实验日期:2013-9-30 姓名: 张胜学号:1007010162 指导教师:程欣宇实验序号:一实验成绩: 一、实验名称 分治算法实验 - 棋盘覆盖问题 二、实验目的及要求 1、熟悉递归算法编写; 2、理解分治算法的特点; 3、掌握分治算法的基本结构。 三、实验环境 Visual C++ 四、实验内容 根据教材上分析的棋盘覆盖问题的求解思路,进行验证性实验; 要求完成棋盘覆盖问题的输入、分治求解、输出。有余力的同学尝试消去递归求解。 五、算法描述及实验步骤 分治算法原理: 分治算法将大的分解成形状结构相同的子问题,并且不断递归地分解,直到子问题规模小到可以直接求解。 棋盘覆盖问题描述: 在一个2k x 2k个方格组成的棋盘中恰有一个方格与其他的不同称为特殊方格,想要求利用四种L型骨牌(每个骨牌可覆盖三个方格)不相互重叠覆盖的将除了特殊方格外的其他方格覆盖。 实验步骤: 1、定义用于输入和输出的数据结构; 2、完成分治算法的编写; 3、测试记录结构; 4、有余力的同学尝试不改变输入输出结构,将递归消除,并说明能否不用栈,直接消除递归,为什么, 六、调试过程及实验结果 实验运行结果: 七、总结 通过本次实验,我更深的理解了递归和分治策略。代码是书上的算法,加上主函数就行了,用的是C语言编写,很长时间没用了,感觉有点生疏。实验结果有点 问题,就是覆盖棋盘时,并不是按照1,2,3….的字符顺序,而是按照很乱的顺序输出字符,这个我不知道怎么解决,就没解决。 八、附录 #include "stdio.h" #include "conio.h" int board[8][8] ={ {0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0 ,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0} }; int tile=0; void chessBoard(int tr, int tc, int dr, int dc, int size) { int t=tile++, s=size/2; if (size==1) return; if (dr算法分析与设计实验报告一
算法设计与分析---回溯实验报告
算法设计与分析实验
算法与设计实验报告
算法设计与分析实验报告
算法设计与分析实验报告棋盘覆盖问题
= tc+s) chessBoard(tr,tc+s,dr,dc,s); 算法分析与设计实验报告-合并排序、快速排序