算法_分治策略分析

算法_分治策略分析
算法_分治策略分析

实验报告

(2016/2017学年第二学期)

课程名称算法分析与设计

实验名称分治策略

实验时间2017 年 3 月30 日指导单位计算机学院软件工程系

指导教师怡婷

学生霍淇滨班级学号B15041236 学院(系) 计算机学院专业软件工程

实验报告

实验报告 分治与递归

实验报告分治与递归 中国矿业大学计算机科学与技术学院孟靖宇 一、实验目的与要求 1、熟悉C/C++语言的集成开发环境; 2、通过本实验加深对递归过程的理解 二、实验内容: 掌握递归算法的概念和基本思想,分析并掌握“整数划分”问题的递归算法。 三、实验题 任意输入一个整数,输出结果能够用递归方法实现整数的划分。 四、算法思想 对于数据n,递归计算最大加数等于x 的划分个数+最大加数不大于x-1的划分个数。最大加数x 从n 开始,逐步变小为n-1, (1) 考虑增加一个自变量:对于数据n,最大加数n1不大于m 的划分个数记作),(m n q 。则有: ???????>>=<==-+--+=1 1,1),()1,()1,(1),(1),(m n m n m n m n m m n q m n q n n q n n q m n q 五、代码实现 #include "stdafx.h" #include #include #include using namespace std; int q(intn,int m); int main(){ int n; cout<<"请输入要划分的整数:"<>n; int p=q(n,n); cout<<"正整数"<

return 0; } int q(intn,int m){ if((n<1)||(m<1)) return 0; if((n==1)||(m==1)) return 1; if(n

算法分析实验报告--分治策略

《算法设计与分析》实验报告 分治策略 姓名:XXX 专业班级:XXX 学号:XXX 指导教师:XXX 完成日期:XXX

一、试验名称:分治策略 (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 #include #define MAX 10 using 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) {

递归与分治

分治算法 一、分治算法 分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。 分治法解题的一般步骤: (1)分解,将要解决的问题划分成若干规模较小的同类问题; (2)求解,当子问题划分得足够小时,用较简单的方法解决; (3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解。 当我们求解某些问题时,由于这些问题要处理的数据相当多,或求解过程相当复杂,使得直接求解法在时间上相当长,或者根本无法直接求出。对于这类问题,我们往往先把它分解成几个子问题,找到求出这几个子问题的解法后,再找到合适的方法,把它们组合成求整个问题的解法。如果这些子问题还较大,难以解决,可以再把它们分成几个更小的子问题,以此类推,直至可以直接求出解为止。这就是分治策略的基本思想。下面通过实例加以说明。 【例1】[找出伪币] 给你一个装有1 6个硬币的袋子。1 6个硬币中有一个是伪造的,并且那个伪造的硬币比真的硬币要轻一些。你的任务是找出这个伪造的硬币。为了帮助你完成这一任务,将提供一台可用来比较两组硬币重量的仪器,利用这台仪器,可以知道两组硬币的重量是否相同。比较硬币1与硬币2的重量。假如硬币1比硬币2轻,则硬币1是伪造的;假如硬币2比硬币1轻,则硬币2是伪造的。这样就完成了任务。假如两硬币重量相等,则比较硬币3和硬币4。同样,假如有一个硬币轻一些,则寻找伪币的任务完成。假如两硬币重量相等,则继续比较硬币5和硬币6。按照这种方式,可以最多通过8次比较来判断伪币的存在并找出这一伪币。 另外一种方法就是利用分而治之方法。假如把1 6硬币的例子看成一个大的问题。第一步,把这一问题分成两个小问题。随机选择8个硬币作为第一组称为A组,剩下的8个硬币作为第二组称为B组。这样,就把1 6个硬币的问题分成两个8硬币的问题来解决。第二步,判断A和B组中是否有伪币。可以利用仪器来比较A组硬币和B组硬币的重量。假如两组硬币重量相等,则可以判断伪币不存在。假如两组硬币重量不相等,则存在伪币,并且可以判断它位于较轻的那一组硬币中。最后,在第三步中,用第二步的结果得出原先1 6个硬币问题的答案。若仅仅判断硬币是否存在,则第三步非常简单。无论A组还是B组中有伪币,都可以推断这1 6个硬币中存在伪币。因此,仅仅通过一次重量的比较,就可以判断伪币是否存在。

算法设计与分析实验报告

本科实验报告 课程名称:算法设计与分析 实验项目:递归与分治算法 实验地点:计算机系实验楼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.代码设计:

实验三分治算法.doc

华东师范大学计算机科学技术系上机实践报告 课程名称:算法设计与分析年级:05上机实践成绩: 指导教师:柳银萍姓名: 上机实践名称:分治算法学号:上机实践日期:2007-4-24 上机实践编号:NO.3组号:上机实践时间:10:00-11:30 一、目的 二、内容与设计思想 1.在一个数组A[1..n] 中,同时寻找最大值和最小值[假设n 为2 的方幂]。并给出你的算法的复杂度分析。 要求: 输入:第一行为一个正整数N(0

析。 要求: 输入:输入有多组测试数据,每个输入占两行,第一行表示整数A,第二行表示整数B。. 输出:输出A*B。 3.1其思路是: 3.2具体算法是: 3.3其复杂度分析: 三、使用环境 四、调试过程 五、总结 六、附录 1. 求最值问题的程序: (此处放程序) 运行结果: 2. 求次最大值问题的程序: (此处放程序) 运行结果: 3.大整数乘积问题的程序:

算法设计实验一归并排序(分治)和插入排序的比较分析

沈阳化工大学实验报告 课程名称算法设计与分析 项目名称归并排序(分治)和插入排序的比较 学院应用技术学院 专业计中职1401 指导教师张雪 报告人张庭浩学号 1422030125 实验时间 2016.11.05 提交时间 2016.11.05

一、实验目的 1.理解和掌握分治算法的相关内容。 2.具体完成插入排序和归并排序性能的比较。 二、实验内容 编写一个真随机函数,随机产生大量数字。在产生相同的一组大量随机数字后,分别用归并排序和插入排序两种算法进行排序,并通过时间函数分别计算出运行的时间。 三、伪代码 1.归并排序 /*数组a[]是原始数组,数组b[]是目标数组*/ 归并排序(数组a[],数组b[]){ `分割与归并(数组a[],0, a.length,数组b[]) } /*通过递归把要排序的子序列分的足够小*/ 分割与归并(数组a[],起始位置,结束位置,数组b[]){ if(结束位置- 起始位置< 2) 返回 中间位置= (起始位置+结束位置)/2 分割与归并(数组a[],起始位置,中间位置,数组b[]) 分割与归并(数组a[],中间位置,结束位置,数组b[]) 归并(数组a[],起始位置,中间位置,结束位置,数组b[]) 拷贝(数组a[],起始位置,结束位置,数组b[]) } 归并(数组a[],起始位置,中间位置,结束位置,数组b[]){ i0 = 起始位置,i1 = 中间位置 for j = 起始位置到结束位置 if(i0 < 中间位置且(i1 > 结束位置或a[i0] <= a[i1]){ //当i0没有超过中间位置时,有两种情况要将a[i0]复制到b[j]上: //1.i1已经超过结束位置,只要把剩下的复制过来就好; //2.a[i0]比a[i1]小 b[j]=a[i0] i0++ } else { b[j]=a[i1] i1++ } }

递归与分治实验报告

递归与分治实验报告 班级:计科1102 姓名:赵春晓学号:2011310200631 实验目的:进一步掌握递归与分治算法的设计思想,通过实际问题来应用递归与分治设计算法。 实际问题:1集合划分问题,2输油管道问题,3邮局选址问题,4整数因子分解问题,5众数问题。 问题1:集合划分 算法思想:对于n个元素的集合,可以划分为由m个子集构成的集合,例如{{1,2}{3,4}}就是由2个子集构成的非空子集。假设f(n,m)表示将n个元素划分成由m个子集构成的集合的个数。那么1)若m == 1 ,则f(n,m)= 1 ;2)若n == m ,则f(n,m)= 1 ;3)若不是上面两种情况则有下面两种情况构成:3.1)向n-1个元素划分成的m个集合里面添加一个新的元素,则有m*f(n-1,m)种方法;3.2)向n-1个元素划分成的m-1个集合里添加一个由一个元素形成的独立的集合,则有f(n-1,m-1)种方法。 实验代码: #include #include using namespace std ; int jihehuafen( int n , int m ) { if( m == 1 || n == m ) return 1 ; else return jihehuafen( n - 1 , m - 1 ) + m*jihehuafen( n - 1 , m ) ; } int main() { ifstream fin("C:/input.txt") ; ofstream fout("C:/output.txt") ; int N , M , num ; fin >> N >> M ; num = jihehuafen( N , M) ; fout << num << endl ; return 0 ; } 问题2:输油管道 算法思想:由于主管道由东向西铺设。故主管道的铺设位置只和各油井的y坐标有关。要使主管道的y坐标最小,主管道的位置y坐标应是各个油井y坐标的中位数。先用快速排序法把各个油井的y坐标排序,然后取其中位数再计算各个油

分治法实验报告一

宁波工程学院电信学院计算机系 实验报告 课程名称:算法设计与分析实验项目:用分治法算法解 最接近点对问题 指导教师:崔迪 实验位置:软件工程实验室姓名: 班级: 学号: 日期: 2016/10/12 一、实验目的 通过上机实验,要求掌握分治法算法的问题描述、算法设计思想、程序设 计和算法复杂性分析等。 二、实验环境: Eclipse 三、实验内容:用分治法解最接近点对问题 (1)问题描述 给定平面S上n个点,找其中的一对点,使得在n(n-1)/2 个点对中,该 点对的距离最小。 (2)算法设计思想 1. n较小时直接求 (n=2). 2.将S上的n个点分成大致相等的2个子集S1和S2 3.分别求S1和S2中的最接近点对 4.求一点在S1、另一点在S2中的最近点对 5.从上述三对点中找距离最近的一对.

(3)程序设计(程序清单及说明) package closestpair; import java.util.Arrays; import https://www.360docs.net/doc/e312430779.html,parator; import java.util.Random; import java.util.Scanner; //定义坐标点 class Point { double x; double y; public Point(double x, double y) { this.x = x; this.y = y; } } // 根据x坐标排序 class MyComparatorX implements Comparator { @Override public int compare(Point p1, Point p2) { if (p1.x < p2.x) { return -1; } else if (p1.x > p2.x) { return 1; } else { return 0; } } } // 根据Y坐标排序 class MyComparatorY implements Comparator { @Override public int compare(Point p1, Point p2) { if (p1.y < p2.y) { return -1; } else if (p1.y > p2.y) { return 1; } else {

算法分析与设计实验一递归与分治策略

实验一递归与分治策略 实验目的 1.了解并掌握递归的概念,递归算法的基本思想; 2.掌握分治法的基本思想方法; 3.了解适用于用分治法求解的问题类型,并能用递归或非递归的方式设计相应的分治法算法; 4.掌握分治法复杂性分析方法,比较同一个问题的递归算法与循环迭代算法的效率。预习与实验要求 1.预习实验指导书及教材的有关内容,掌握分治法的基本思想; 2.严格按照实验内容进行实验,培养良好的算法设计和编程的习惯; 3.认真听讲,服从安排,独立思考并完成实验。 实验原理 简单说来,当一个函数用它自己来定义时就称为递归。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。因此,在考虑使用递归算法编写程序时,应满足两点:1)该问题能够被递归形式描述;2)存在递归结束的边界条件。递归的能力在于用有限的语句来定义对象的无限集合。用递归思想写出的程序往往十分简洁易懂。一般说来,一个递归算法可以转换称为一个与之等效的非递归算法,但转换后的非递归算法代码将成倍地增加。 分治是一种被广泛应用的有效方法,它的基本思想是把最初的问题分解成若干子问题,然后在逐个解决各个子问题的基础上得到原始问题的解。所谓分治就是“分而治之”的意思。由于分解出的每个子问题总是要比最初的问题容易些,因而分治策略往往能够降低原始问题的难度,或者提高解决原始问题的效率。 根据如何由分解出的子问题求出原始问题的解,分治策略又可分为两种情形:第一,原始问题的解只存在于分解出的某一个子问题中,则只需要在原始问题的一个划分中求解即可;第二,原始问题的解需要由各个子问题的解再经过综合处理得到。无论是哪一种情况,分治策略可以较快地缩小问题的求解范围,从而加快问题求解的速度。 分治策略运用于计算机算法是,往往会出现分解出来的子问题与原始问题类型相同的现象,而与原问题相比,各个子问题的规模变小了,这刚好符合递归的特征。因此分治策略往往是和递归联系在一起的。

(完整word版)分治法循环赛日程表实验报告

西北农林科技大学信息工程学院《算法分析与设计》综合训练实习报告 题目:分治法循环赛日程表 学号 姓名 专业班级 指导教师 实践日期2011年5月16日-5月20日

目录 一、综合训练目的与要求 (1) 二、综合训练任务描述 (1) 三、算法设计 (1) 四、详细设计及说明 (3) 五、调试与测试 (4) 六、实习日志 (6) 七、实习总结 (6) 八、附录:核心代码清单 (6)

一、综合训练目的与要求 本综合训练是软件工程专业重要的实践性环节之一,是在学生学习完《算法分析》课程后进行的综合练习。本课综合训练的目的和任务: (1)巩固和加深学生对算法分析课程基本知识的理解和掌握; (2)培养利用算法知识解决实际问题的能力; (3)掌握利用程序设计语言进行算法程序的开发、调试、测试的能力; (4)掌握书写算法设计说明文档的能力; (5)提高综合运用算法、程序设计语言、数据结构知识的能力。 二、综合训练任务描述 假设有n=2k 个运动员要进行网球循环赛。设计一个满足一下要求的比赛日程表:(1)每个选手必须与其他n-1个选手各赛一次 (2)每个选手一天只能赛一次 (3)循环赛一共进行n-1天 利用Java语言开发一个界面,输入运动员的个数,输出比赛日程表。对于输入运动员数目不满足n=2k时,弹出信息提示用户。 三、算法设计 (1) 文字描述 假设n位选手顺序编号为1,2,3……n,比赛的日程表是一个n行n-1列的表格。第i行j列表示第i号选手在第j天的比赛对手,根据分治法,要求n个选手的比赛日程,只要知道其中一半的比赛日程,所以使用递归最终可以分到计算两位选手的比赛日程,然后逐级合并,得出结果。 (2) 框图

算法设计与分析:递归与分治法-实验报告

应用数学学院信息安全专业班学号姓名 实验题目递归与分治法 综合实验评分表

实验报告 一、实验目的与要求 1.掌握递归算法的设计思想 2.掌握分治法设计算法的一般过程 3.理解并掌握算法渐近时间复杂度的分析方法 二、实验内容 1、折半查找的递归算法 (1)源程序代码 #include #include using namespace std; int bin_search(int key[],int low, int high,int k) { int mid; if(low>high) return -1; else{ mid = (low+high) / 2; if(key[mid]==k) return mid; if(k>key[mid]) return bin_search(key,mid+1,high,k); else return bin_search(key,low,mid-1,k); } } int main() { int n , i , addr; int A[10] = {2,3,5,7,8,10,12,15,19,21}; cout << "在下面的10个整数中进行查找" << endl; for(i=0;i<10;i++){ cout << A[i] << " " ; } cout << endl << endl << "请输入一个要查找的整数" << endl; cin >> n; addr = bin_search(A,0,9,n);

if(-1 != addr) cout << endl << n << "是上述整数中的第" << addr << "个数" << endl; else cout << endl << n << "不在上述的整数中" << endl << endl; getchar(); return 0; } (2)运行界面 ①查找成功 ②查找失败

算法分析实验报告--分治策略

分治策略 姓名:XXX 专业班级:XXX 学号:XXX 指导教师:XXX 完成日期:XXX

一、试验名称:分治策略 (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 #include<> #define MAX 10 using 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 (a[--j]>x); if (i>=j) { break; } Swap(a[i],a[j]); } a[p] = a[j]; //将基准元素放在合适的位置 a[j] = x; return j; } //通过RandomizedPartition函数来产生随机的划分 template vclass Type> int RandomizedPartition(Type a[], int p, int r) { int i = Random(p,r); Swap(a[i],a[p]); return Partition(a,p,r); } 较小个数排序序列的结果: 测试结果 较大个数排序序列的结果:

实验心得 快速排序在之前的数据结构中也是学过的,在几大排序算法中,快速排序和归并排序尤其是 重中之重,之前的快速排序都是给定确定的轴值,所以存在一些极端的情况使得时间复杂度 很高,排序的效果并不是很好,现在学习的一种利用随机化的快速排序算法,通过随机的确 定轴值,从而可以期望划分是较对称 的,减少了出现极端情况的次数,使得排序的效率挺高了很多, 化算法想呼应,而且关键的是对于随机生成函数,通过这一次的 学习终于弄明白是怎么回事了,不错。 与后面的随机实 验和自己的 实验得分助教签名 附录: 完整代码(分治法) //随机后标记元素后的快速排序 #i nclude #in elude #inelude #include using namespacestd; template < class Type> void S &x,Type &y); // 声明swap函数 inline int Random(int x, int y); // 声明内联函数 template < class Type> int Partition(Type a[], int p, int r); // 声明 Partition 函数template int RandomizedPartition(Type a[], int p, int r); // 声明 RandomizedPartition 函数 int a[1000000]; //定义全局变量用来存放要查找的数组 更大个数排序序列的结果:

使用分治策略递归和非递归和递推算法解决循环赛日程表课程设计报告

《算法设计与分析》 课程设计报告 题目:循环赛日程表 院(系):信息科学与工程学院 专业班级:软工 学生姓名: 学号: 指导教师: 2018 年 1 月 8 日至 2018 年 1 月 19 日

算法设计与分析课程设计任务书

目录 1 常用算法 (1) 1.1分治算法 (1) 基本概念: (1) 1.2递推算法 (2) 2 问题分析及算法设计 (5) 2.1分治策略递归算法的设计 (5) 2.2 分治策略非递归算法的设计 (7) 2.3 递推策略算法的设计 (8) 3 算法实现 (9) 3.1分治策略递归算法的实现 (9) 3.2 分治策略非递归算法的实现 (10) 3.3 递推策略算法的实现 (12) 4 测试和分析 (15) 4.1分治策略递归算法测试 (15) 4.2分治策略递归算法时间复杂度的分析 (16) 4.3 分治策略非递归算法测试 (16) 4.4分治策略非递归算法时间复杂度的分析 (17) 时间复杂度为:O(5^(n-1)) (17) 4.5 递推策略算法测试 (17) 4.6 递推策略算法时间复杂度的分析 (18) 时间复杂度为:O(5^(n-1)) (18) 4.7 三种算法的比较 (18) 5 总结 (19) 参考文献 (20)

1 常用算法 1.1分治算法 基本概念: 在计算机科学中,分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)…… 任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。问题的规模越小,越容易直接求解,解题所需的计算时间也越少。例如,对于n个元素的排序问题,当n=1时,不需任何计算。n=2时,只要作一次比较即可排好序。n=3时只要作3次比较即可,…。而当n较大时,问题就不那么容易处理了。要想直接解决一个规模较大的问题,有时是相当困难的。 基本思想及策略: 分治法的设计思想是:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。 分治策略是:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。 如果原问题可分割成k个子问题,1

算法实验报告

实验一分治与递归算法的应用 一、实验目的 1.掌握分治算法的基本思想(分-治-合)、技巧和效率分析方法。 2.熟练掌握用递归设计分治算法的基本步骤(基准与递归方程)。 3.学会利用分治算法解决实际问题。 二 . 实验内容 金块问题 老板有一袋金块(共n块,n是2的幂(n≥2)),最优秀的雇员得到其中最重的一块,最差的雇员得到其中最轻的一块。假设有一台比较重量的仪器,希望用最少的比较次数找出最重和最轻的金块。并对自己的程序进行复杂性分析。 三.问题分析: 一般思路:假设袋中有n 个金块。可以用函数M a x(程序 1 - 3 1)通过n-1次比较找到最重的金块。找到最重的金块后, 可以从余下的n-1个金块中用类似法通过n-2次比较找出最轻的金块。这样,比较的总次数为2n-3。

分治法:当n很小时,比如说,n≤2,识别出最重和最轻的金块,一次比较就足够了。当n 较大时(n>2),第一步,把这袋金块平分成两个小袋A和B。第二步,分别找出在A和B中最重和最轻的金块。设A中最重和最轻的金块分别为HA 与LA,以此类推,B中最重和最轻的金块分别为HB 和LB。第三步,通过比较HA 和HB,可以找到所有金块中最重的;通过比较LA 和LB,可以找到所有金块中最轻的。在第二步中,若n>2,则递归地应用分而治之方法 程序设计 据上述步骤,可以得出程序1 4 - 1的非递归代码。该程序用于寻找到数组w [ 0 : n - 1 ]中的最小数和最大数,若n < 1,则程序返回f a l s e,否则返回t r u e。 当n≥1时,程序1 4 - 1给M i n和M a x置初值以使w [ M i n ]是最小的重量,w [ M a x ]为最大的重量。 首先处理n≤1的情况。若n>1且为奇数,第一个重量w [ 0 ]将成为最小值和最大值的候选值,因此将有偶,数个重量值w [ 1 : n - 1 ]参与f o r循环。当n 是偶数时,首先将两个重量值放在for 循环外进行比较,较小和较大的重量值分别置为Min和Max,因此也有偶数个重量值w[2:n-1]参与for循环。 在for 循环中,外层if 通过比较确定( w [ i ] , w [ i + 1 ] )中的较大和较小者。此工作与前面提到的分而治之算法步骤中的2) 相对应,而内层的i f负责找出较小重量值和较大重量值中的最小值和最大值,

-实验1分治法

一、实验目的 1.理解分治法的方法; 2. 掌握使用分治法解决一般问题的步骤; 3. 掌握分治算法求解数组的最大值和最小值的方法。 二、实验原理 在一个给定数组中查找最大值和最小值是一类常见的问题,也是解决其他一些算法的基础。 假设给定数组为a,数组中含有n个元素,一般的算法是在数组中进行直接 循环的次数在算法第2行给出,为(n-2)+1=n-1次,因此,算法元素比较总次数为2(n-1)次。 现在采用分治的思想,假设数组的长度为2的整数幂,将数组分割成两半,分别为a[0…(n/2)-1]和a[n/2…n-1],在每一半中分别查找最大值和最小值,并返回这两个最小值中的最小值以及两个最大值中的最大值。 假设给定数组为a,数组的下标上界和下界分别为low和high,则其算法伪 接比较数组的两个元素,选出最大值和最小值,此为函数的递归终止条件;代码第7行和第8行是两个递归调用,分别在数组的下标范围[low,mid]和 [mid+1,high]查找最小值和最大值,第9行比较两个最大值取其中较大者,第10行比较两个最小值取较大者。

代码的第2、9和10行涉及到元素的比较,第7、8行由于递归也产生元素比较,因此令算法总的元素比较次数为C(n),则有 ???>+==2 2)2/(221)(n n C n n C 若若 对递推式进行求解 2 2/3 2 2)2/( 2)2(2 2 2...22)2/(2 ... 2 48)8/(824)2)8/(2(4 2 4)4/(42)2)4/(2(22)2/(2)(1 1122111-=-+=+=+++++==+++=+++=++=++=+=∑-=-----n n C n C n C n C n C n C n C n C k k j j k k k k k 得到minmax 算法的元素比较总次数为3n/2-2,优于直接比较的性能。 三、实验内容及要求 1. 编写程序使用分治算法MINMAX 求解数组的最小值和最大值,并用实际数组对算法进行测试。 2. 要求算法中元素比较的次数为3n/2-2,在程序中元素比较的地方进行记录,并在程序末尾输出数组最大值和最小值以及元素比较次数。 四、实验步骤 1. 定义结构体类型或类,用以在函数的返回值同时返回数组的最大值和最小值。

分治算法实验报告

算法分析与设计实验报告 第 1 次实验

附录:完整代码 SelectMaxMin.cpp: #include #include #include #include #include using namespace std; void SelectMaxMin(int *a,inti,intj,int&max,int&min) { if(i==j) { max= a[i]; min =a[i]; return; } else { int mid=(i+j)/2; intmaxi,maxj,mini,minj; SelectMaxMin(a,i,(i+j)/2,maxi,mini); SelectMaxMin(a,((i+j)/2)+1,j,maxj,minj); if(maxi>maxj) max=maxi; else max=maxj; if(mini

else min=minj; return; } } intmain() { clock_tstart,end,over; start=clock(); end=clock(); over=end-start; start=clock(); //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int m; cout<<"Please input the number : "; cin>> m; int a[m]; srand((unsigned int)time(NULL)); cout<< "随机产生的数据(0-100):"; for(inti=0; i

实验一 递归与分治策略算法设计与实现实验报告

华北水利水电学院算法分析与设计实验报告 20010~2011学年第二学期2008级计算机科学与技术专业 班级:2008109 学号:200810906 姓名:刘景超 实验一递归与分治算法的设计与实现 一、实验目的: 1、了解递归、分治算法的设计思路与设计技巧,理解递归的概念,掌握设计有效算法的 分治策略。 2、通过实际案例,领会算法的执行效率 二、试验内容: 棋盘覆盖、最接近点对、排序算法、矩阵乘法等,(也可选作其它问题); 三、核心程序源代码: #include #include void main() { void hanoi(int n,char one,char two,char three); int m; cout<<"请输入要移动的盘子的数目:"<>m; cout<<"盘子的数目为:"<"<

五、小结 本想用MFC采用图形的方式展示移动的过程,可惜水平有限,实在是写不出来,只好采用控制台程序了。采用控制台程序表述还是很简单的,算法也不复杂。这次实验让我认识到我在MFC方面基础还很薄弱,还需要多多练习,慢慢提升自己。

实验1++递归与分治算法

淮海工学院计算机工程学院实验报告书 课程名:《算法分析与设计》 题目:实验1 递归与分治算法 班级: 学号: 姓名:

实验1 递归与分治算法 实验目的和要求 (1)进一步掌握递归算法的设计思想以及递归程序的调试技术; (2)理解这样一个观点:分治与递归经常同时应用在算法设计之中。 (3)分别用蛮力法和分治法求解最近对问题; (4)分析算法的时间性能,设计实验程序验证分析结论。 实验内容 设p1=(x1, y1), p2=(x2, y2), …, pn=(xn, yn)是平面上n个点构成的集合S,设计算法找出集合S中距离最近的点对。 实验环境 Turbo C 或VC++ 实验学时 2学时,必做实验 数据结构与算法 核心源代码 蛮力法: #include #include #include int ClosestPoints(int x[ ], int y[ ], int n); int main() { int x[3],y[3]; printf("请输入各点的横坐标: "); for(int i=0;i<4;i++) { scanf("%d",&x[i]); } printf("请输入各点的纵坐标: "); for(int j=0;j<4;j++)

{ scanf("%d",&y[i]); } ClosestPoints(x,y,4); return 0; } int ClosestPoints(int x[ ], int y[ ], int n) { int index1, index2; //记载最近点对的下标 int d, minDist = 1000; //假设最大距离不超过1000 for (int i = 0; i < n - 1; i++) for (int j = i + 1; j < n; j++) //只考虑i<j的点对 { d =sqrt ((x[i]-x[j])* (x[i]-x[j]) + (y[i]-y[j])* (y[i]-y[j])); if (d < minDist) { minDist = d; index1 = i; index2 = j; } } cout<<"最近的点对是:"< #include const int n = 4; struct point //定义点的结构体 { int x, y; };

相关文档
最新文档