算法设计与分析实验报告 频道分配问题
算法设计与分析实验报告

实验报告题目实验一递归与分治策略一、实验目的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 intint 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.提高学生综合应用所学知识解决实际问题的能力。
算法分析与设计-实验四 作业调度问题-实验报告

南阳理工学院算法分析与设计实验报告册开课学院:计算机与软件学院实验项目:实验4:贪心法(作业调度问题)实验时间:第10周周3(3,4)节实验地点: 15#515指导教师:学生姓名:学生学号:专业班级:2020-2021学年第1学期一、实验目的1.了解贪心算法思想及基本原理2.掌握使用贪心算法求解问题的一般特征3.能够针对实际问题,能够正确选择贪心策略4.能够针对选择的贪心策略,证明算法的正确性5.能够根据贪心策略,正确编码6.能够正确分析算法的时间复杂度和空间复杂度二、实验平台1.JDK1.82.IDEA三、实验内容设有n个独立的作业{1, 2, …,n},由m台相同的机器{M1, M2, …,Mm}进行加工处理,作业i所需的处理时间为ti (1≤i≤n),每个作业均可在任何一台机器上加工处理,但不可间断、拆分。
多机调度问题要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m台机器加工处理完成。
提示:贪心法求解多机调度问题的贪心策略是最长处理时间作业优先,即把处理时间最长的作业分配给最先空闲的机器,这样可以保证处理时间长的作业优先处理,从而在整体上获得尽可能短的处理时间。
按照最长处理时间作业优先的贪心策略,当m≥n时,只要将机器i的[0, ti)时间区间分配给作业i即可;当m<n时,首先将n 个作业依其所需的处理时间从大到小排序,然后依此顺序将作业分配给空闲的处理机。
四、算法设计1.问题分析设有n个独立的作业{1, 2, …, n}, 由m台相同的机器进行加工处理. 作业i所需时间为t i. 约定:任何作业可以在任何一台机器上加工处理, 但未完工前不允许中断处理,任何作业不能拆分成更小的子作业。
要求给出一种作业调度方案,使所给的n 个作业在尽可能短的时间内由m台机器加工处理完成。
多机调度问题是一个NP完全问题,到目前为止还没有完全有效的解法。
对于这类问题,用贪心选择策略有时可以设计出一个比较好的近似算法。
《算法设计与分析》实验报告实验一...

《算法设计与分析》实验报告实验一递归与分治策略应用基础学号:**************姓名:*************班级:*************日期:2014-2015学年第1学期第九周一、实验目的1、理解递归的概念和分治法的基本思想2、了解适用递归与分治策略的问题类型,并能设计相应的分治策略算法3、掌握递归与分治算法时间空间复杂度分析,以及问题复杂性分析方法二、实验内容任务:以下题目要求应用递归与分治策略设计解决方案,本次实验成绩按百分制计,完成各小题的得分如下,每小题要求算法描述准确且程序运行正确。
1、求n个元素的全排。
(30分)2、解决一个2k*2k的特殊棋牌上的L型骨牌覆盖问题。
(30分)3、设有n=2k个运动员要进行网球循环赛。
设计一个满足要求的比赛日程表。
(40分)提交结果:算法设计分析思路、源代码及其分析说明和测试运行报告。
三、设计分析四、算法描述及程序五、测试与分析六、实验总结与体会#include "iostream"using namespace std;#define N 100void Perm(int* list, int k, int m){if (k == m){for (int i=0; i<m; i++)cout << list[i] << " ";cout << endl;return;}else{for (int i=m; i<k; i++){swap(list[m], list[i]);Perm(list, k, m+1);swap(list[m], list[i]);}}}void swap(int a,int b){int temp;temp=a;a=b;b=temp;}int main(){int i,n;int a[N];cout<<"请输入排列数据总个数:";cin>>n;cout<<"请输入数据:";for(i=0;i<n;i++){cin>>a[i];}cout<<"该数据的全排列:"<<endl;Perm(a,n,0);return 0;}《算法设计与分析》实验报告实验二递归与分治策略应用提高学号:**************姓名:*************班级:*************日期:2014-2015学年第1学期一、实验目的1、深入理解递归的概念和分治法的基本思想2、正确使用递归与分治策略设计相应的问题的算法3、掌握递归与分治算法时间空间复杂度分析,以及问题复杂性分析方法二、实验内容任务:从以下题目中任选一题完成,要求应用递归与分治策略设计解决方案。
算法分析与设计实验报告

算法分析与设计实验报告算法分析与设计实验报告一、引言算法是计算机科学的核心,它们是解决问题的有效工具。
算法分析与设计是计算机科学中的重要课题,通过对算法的分析与设计,我们可以优化计算机程序的效率,提高计算机系统的性能。
本实验报告旨在介绍算法分析与设计的基本概念和方法,并通过实验验证这些方法的有效性。
二、算法分析算法分析是评估算法性能的过程。
在实际应用中,我们常常需要比较不同算法的效率和资源消耗,以选择最适合的算法。
常用的算法分析方法包括时间复杂度和空间复杂度。
1. 时间复杂度时间复杂度衡量了算法执行所需的时间。
通常用大O表示法表示时间复杂度,表示算法的最坏情况下的运行时间。
常见的时间复杂度有O(1)、O(log n)、O(n)、O(n log n)和O(n^2)等。
其中,O(1)表示常数时间复杂度,O(log n)表示对数时间复杂度,O(n)表示线性时间复杂度,O(n log n)表示线性对数时间复杂度,O(n^2)表示平方时间复杂度。
2. 空间复杂度空间复杂度衡量了算法执行所需的存储空间。
通常用大O表示法表示空间复杂度,表示算法所需的额外存储空间。
常见的空间复杂度有O(1)、O(n)和O(n^2)等。
其中,O(1)表示常数空间复杂度,O(n)表示线性空间复杂度,O(n^2)表示平方空间复杂度。
三、算法设计算法设计是构思和实现算法的过程。
好的算法设计能够提高算法的效率和可靠性。
常用的算法设计方法包括贪心算法、动态规划、分治法和回溯法等。
1. 贪心算法贪心算法是一种简单而高效的算法设计方法。
它通过每一步选择局部最优解,最终得到全局最优解。
贪心算法的时间复杂度通常较低,但不能保证得到最优解。
2. 动态规划动态规划是一种将问题分解为子问题并以自底向上的方式求解的算法设计方法。
它通过保存子问题的解,避免重复计算,提高算法的效率。
动态规划适用于具有重叠子问题和最优子结构的问题。
3. 分治法分治法是一种将问题分解为更小规模的子问题并以递归的方式求解的算法设计方法。
算法设计与分析实验报告(中南民族大学)

院系:计算机科学学院专业:年级:课程名称:算法设计与分析基础班号:组号:指导教师:年月日实验结果及分析1.求最大数2.递归法与迭代法性能比较递归迭代3.改进算法1.利用公式法对第n项Fibonacci数求解时可能会得出错误结果。
主要原因是由于double类型的精度还不够,所以程序算出来的结果会有误差,要把公式展开计算。
2.由于递归调用栈是一个费时的过程,通过递归法和迭代法的比较表明,虽然递归算法的代码更精简更有可读性,但是执行速度无法满足大数问题的求解。
3.在当前计算机的空间较大的情况下,在一些速度较慢的问题中,空间换时间是一个比较周全的策略。
实验原理(算法基本思想)定义:若A=(a ij), B=(b ij)是n×n的方阵,则对i,j=1,2,…n,定义乘积C=A⋅B 中的元素c ij为:1.分块解法通常的做法是将矩阵进行分块相乘,如下图所示:二.Strassen解法分治法思想将问题实例划分为同一问题的几个较小的实例。
对这些较小实例求解,通常使用递归方法,但在问题规模足够小时,也会使用另一种算法。
如果有必要,合并这些问题的解,以得到原始问题的解。
求解矩阵相乘的DAC算法,使用了strassen算法。
DAC(A[],B[],n){If n=2 使用7次乘法的方法求得解ElseDivide(A)//把A分成4块Divide(B)//把B分成4块调用7次strassen算法求得解的4块合并这4块得到解并返回}伪代码Serial_StrassenMultiply(A, B, C) {T1 = A0 + A3;T2 = B0 + B3;StrassenMultiply(T1, T2, M1);T1 = A2 + A3;StrassenMultiply(T1, B0, M2);T1 = (B1 - B3);StrassenMultiply (A0, T1, M3);T1 = B2 - B0;StrassenMultiply(A3, T1, M4);T1 = A0 + A1;StrassenMultiply(T1, B3, M5);T1 = A2 – A0;T2 = B0 + B1;StrassenMultiply(T1, T2, M6);T1 = A1 – A3;T2 = B2 + B3;StrassenMultiply(T1, T2, M7);C0 = M1 + M4 - M5 + M7C1 = M3 + M5C2 = M2 + M4C3 = M1 - M2 + M3 + M6}实验结果及分析时间复杂度1.分块相乘总共用了8次乘法,因而需要Θ(n log28)即Θ(n3)的时间复杂度。
回溯算法实验 - 频道分配问题

} int main() { char ch[27]; while(cin>>lines&&lines)
{ int step = 1; m = 5; memset(set,0,sizeof(set)); memset(result,0,sizeof(result)); for(int i=0;i<lines;i++) { cin>>ch; for(int j=2;ch[j]!='\0';j++) set[i][ch[j]-'A']=1; } result[0] = 1; backtrack(1); if(m==1) cout<<m<<" channel needed."<<endl; else cout<<m<<" channels needed."<<endl; } return 0;
3、 分 析 出 算 法 复 杂 度 图 m 可着色问题的回溯算法的计算时间上界可以通过计算解空间树中内结 点个数来估计。图 m 可着色问题的解空间树中内结点个数是 m i 。对于每一个
i n 1
内结点,在最坏情况下,用 same 检查当前扩展结点的每一个儿子所相应的颜色 的 可 用 性 需 耗 时 O(m n) 。 因 此 , 回 溯 法 总 的 时 间 耗 费 是
四、实验内容
1 、 登 陆 POJ 系 统 , 找 到 题 号 为 1129 的 题 目 - 频 道 分 配 ; 2、 阅 读 题 目 , 分 析 出 求 解 该 问 题 的 思 路 ; 3、 使 用 回 溯 算 法 , 实 现 本 题 ; 4 、 进 行 简 单 测 试 , 完 成 之 后 提 交 到 POJ 系 统 。
算法分析实验报告

《算法设计与分析》实验报告分治策略一、试验名称:分治策略( 1) 写出源程序,并编译运行( 2) 详细记录程序调试及运行结果二、实验目的(1) 了解分治策略算法思想(2) 掌握快速排序、归并排序算法(3) 了解其他分治问题典型算法三、实验内容(1) 编写一个简单的程序,实现归并排序。
(2) 编写一段程序,实现快速排序。
(3) 编写程序实现循环赛日程表。
设有n=2k 个运动员要进行网球循环赛。
现要设计一个满足以下要求的比赛日程表: (1)每个选手必须与其它n-1 个选手各赛一次( 2)每个选手一天只能赛一场( 3)循环赛进行n-1 天四、算法思想分析(1) 编写一个简单的程序,实现归并排序。
将待排序元素分成大小大致相同的 2 个子集合,分别对 2 个子集合进行排序,最终将排好序的子集合合并成为所要求的排好序的集合。
(2) 编写一段程序,实现快速排序。
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
(3) 编写程序实现循环日赛表。
按分治策略,将所有的选手分为两组,n 个选手的比赛日程表就可以通过为n/2 个选手设计的比赛日程表来决定。
递归地用对选手进行分割,直到只剩下 2 个选手时,比赛日程表的制定就变得很简单。
这时只要让这 2 个选手进行比赛就可以了。
五、算法源代码及用户程序(1) 编写一个简单的程序,实现归并排序。
#include<iostream>#include<>#define MAX 10using namespace std;void merge(int array[],int p,int q,int r){int i,k;int begin1,end1,begin2,end2;int* temp = new int[r-p+1];begin1 = p;end1 = q;begin2 = q+1;end2 = r;k = 0;while((begin1 <= end1)&&(begin2 <= end2)){if(array[begin1] < array[begin2]){temp[k] = array[begin1];begin1++;}else{temp[k] = array[begin2];begin2++;}k++;}while(begin1 <= end1) {temp[k++] = array[begin1++];while(begin2 <= end2){temp[k++] = array[begin2++];}for(i = 0;i < (r-p+1);i++){array[p+i] = temp[i];}delete[](temp);}void merge_sort(int data[],int left,int right){if(left < right){int mid = (left + right)/2;merge_sort(data,left,mid);merge_sort(data,mid + 1,right); merge(data,left,mid,right);}}void main(){int number[MAX] = {0};srand(time(NULL));printf(" 排序前:");for(int i = 0; i < MAX; i++) {number[i] = rand() % 100; printf("%d ", number[i]);}cout<<endl;merge_sort(number,0,9);printf(" 排序后:");for(int j = 0; j < MAX; j++) { printf("%d ", number[j]);}(2) 编写一段程序,实现快速排序。
算法设计与分析报告报告材料实验二

实验二:分治法实验一、实验目的(1)掌握设计有效算法的分治策略。
(2)通过快速排序学习分治策略设计技巧二、实验要求(1)熟练掌握分治法的基本思想及其应用实现。
(2)理解所给出的算法,并对其加以改进。
三、分治法的介绍任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。
问题的规模越小,越容易直接求解,解题所需的计算时间也越少。
而当n较大时,问题就不那么容易处理了。
要想直接解决一个规模较大的问题,有时是相当困难的。
分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
如果原问题可分割成k个子问题,1<k≤n ,且这些子问题都可解,并可利用这些子问题的解求出原问题的解,那么这种分治法就是可行的。
由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。
在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易直接求出其解。
这自然导致递归过程的产生。
分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效算法。
分治法的适用条件:(1)该问题的规模缩小到一定的程度就可以容易地解决;(2)该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。
(3)利用该问题分解出的子问题的解可以合并为该问题的解;(4)该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
上述的第一条特征是绝大多数问题都可以满足的,因为问题的计算复杂性一般是随着问题规模的增加而增加;第二条特征是应用分治法的前提,它也是大多数问题可以满足的,此特征反映了递归思想的应用;第三条特征是关键,能否利用分治法完全取决于问题是否具有第三条特征,如果具备了第一条和第二条特征,而不具备第三条特征,则可以考虑贪心法或动态规划法。
第四条特征涉及到分治法的效率,如果各子问题是不独立的,则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然可用分治法,但一般用动态规划法较好。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
贵州大学计算机科学与技术学院
计算机科学与技术系上机实验报告
课程名称:算法设计与分析班级:信计101班实验日期:2013-11-25
姓名:张胜学号:1007010162 指导教师:程欣宇
实验序号:四实验成绩:
一、实验名称
回溯算法实验- 频道分配问题
二、实验目的及要求
1、使用在线测评的算法题目评分系统来测试所写代码;
2、通过直观的应用问题,加深对回溯算法的理解;
三、实验环境
任意C或C++编写调试工具,北京大学ICPC在线测评系统POJ
四、实验内容
1、登陆POJ系统,找到题号为1129的题目-频道分配;
2、阅读题目,分析出求解该问题的思路;
3、使用回溯算法,实现本题;
4、进行简单测试,完成之后提交到POJ系统。
五、算法描述及实验步骤
回溯算法原理:
回溯法是一个既带有系统性又带有跳跃性的搜索算法,用它可以系统地搜索一个问题的所有解或任一解。
它在问题的解空间树中,按深度优先的策略,从根结点出发搜索解空间树。
算法搜索至解空间树的任一结点时,先判断该结点是否包含问题的解。
如果肯定不包含,则跳过对以该结点为根的子树的搜索,逐层向其祖先结点回溯。
否则,进入该子树,继续按深度优先策略搜索。
回溯法求问题的所有解时,要回溯到根,且根结点的所有子树都已经被搜索遍才结束。
回溯法求问题的一个解时,只要搜索到问题的一个解就可结束。
频道分配问题描述:
当一个无线站广播覆盖一个非常大的区域时,需要使用转发器转发增强信号。
然而,每个转发器使用的频道数必须仔细的选择,以使得相邻的转发器之间不会相互干扰。
它们相互不干扰的条件是相邻的转发器使用不同的频道。
因为无线频谱是非常稀有的资源,因此,所给的转发器网络使用的频道数量必须最小化。
你需要写一个程序读出转发器网络的描述,然后算出最小需要的频道数量。
注意:邻接关系具有对称性,如果A邻接B,则B邻接A。
另外,因为转发器网络是平面的,所以通道不会交叉。
输入
输入由若干转发器网络的地图组成。
每个地图的第一个行是转发器数量(1至26,用0表示输入结束)。
每个转发器由字母A至Z标识,每行列出和一个转发器邻接的相邻转发器。
输出
对于每一个转发器网络地图,输出最少占用的频道数量(注意单复数)。
例子输入
2
A:
B:
4
A:BC
B:ACD
C:ABD
D:BC
4
A:BCD
B:ACD
C:ABD
D:ABC
例子输出
1 channel needed.
3 channels needed.
4 channels needed.
实验步骤:
1、建立频道分配问题的解题思路
1、建立频道分配问题的解题思路
首先构建回溯算法的基本框架,对每输入的若干转发器网络的地图(行数:lines),都对其所有可能的路径进行比较,找出相邻路径不同的组合即可。
2、构造算法框架
构造频道分配问题回溯算法如下:
①回溯算法实现
void backtrack(int x)
{
if(x == lines)
{
int get=0;
for(int i=0;i<lines;i++)
{
if(result[i]>get)
get = result[i];
}
if(get<m)
m = get;
return;
}
int j;
for(int i=1;i<=4;i++)
{
for(j=0;j<lines;j++)
{
if(set[x][j]==1&&result[j]==i)
break;
}
if(j==lines){
result[x] = i;
backtrack(x+1);
}
}
}
②主函数调用实现
while(cin>>lines&&lines)
{
int step = 1;
m = 5;
memset(set,0,sizeof(set));
memset(result,0,sizeof(result));
for(int i=0;i<lines;i++)
{
cin>>ch;
for(int j=2;ch[j]!='\0';j++)
set[i][ch[j]-'A']=1;
}
result[0] = 1;
backtrack(1);
3、分析出算法复杂度
根据该算法的调度可知,每输入一个行数,遍历整个子树需要树的深度时间,即O(N)时间,找到一个满足条件的值就跳出。
六、调试过程及实验结果
按照输入示例输入数据如下:
由此可知,调试结果与预期结论一致。
七、总结
通过对本实验的学习,我对回溯算法有了进一步的理解,在解决问题和分析问题上的能力得到了一定的锻炼。
不过,在本次实验过程中,也遇到一些困难,比如,刚开始在算法逻辑上没有考虑周全,使得调试结果屡次出错,后通过同学的查找,我发现了错误并给予解决。
八、附录
#include<iostream>
using namespace std;
#define MAX 27
int set[MAX][MAX];
int result[MAX];
int lines;
int m;
void backtrack(int x)
{
if(x == lines)
{
int get=0;
for(int i=0;i<lines;i++)
{
if(result[i]>get)
get = result[i];
}
if(get<m)
m = get;
return;
}
int j;
for(int i=1;i<=4;i++)
{
for(j=0;j<lines;j++)
{
if(set[x][j]==1&&result[j]==i)
break;
}
if(j==lines){
result[x] = i;
backtrack(x+1);
}
}
}
int main()
{
char ch[27];
while(cin>>lines&&lines)
{
int step = 1;
m = 5;
memset(set,0,sizeof(set));
memset(result,0,sizeof(result));
for(int i=0;i<lines;i++)
{
cin>>ch;
for(int j=2;ch[j]!='\0';j++)
set[i][ch[j]-'A']=1;
}
result[0] = 1;
backtrack(1);
if(m==1)
cout<<m<<" channel needed."<<endl;
else
cout<<m<<" channels needed."<<endl; }
return 0;。