收藏 分享(赏)

算法效率分析与分治法的应用.ppt

上传人:saw518 文档编号:5949385 上传时间:2019-03-21 格式:PPT 页数:53 大小:408KB
下载 相关 举报
算法效率分析与分治法的应用.ppt_第1页
第1页 / 共53页
算法效率分析与分治法的应用.ppt_第2页
第2页 / 共53页
算法效率分析与分治法的应用.ppt_第3页
第3页 / 共53页
算法效率分析与分治法的应用.ppt_第4页
第4页 / 共53页
算法效率分析与分治法的应用.ppt_第5页
第5页 / 共53页
点击查看更多>>
资源描述

1、算法效率与分治算法的应用,长沙市一中 曹利国,算法效率的评价,算法的评估 有时求解同一个问题常常有多种可用的算法,在一定的条件下当然要选择使用好的算法。用什么方法评估算法的好坏呢?通常使用算法复杂性这一概念来评估算法。,算法评价,算法执行时间需通过依据该算法编制的程序在计算机上运行时所消耗的时间来度量。而度量一个程序的执行时间通常有两种方法: 事后统计的方法 事前分析估算的方法,算法评价,一个用高级程序语言编写的程序在计算机上运行时所消耗的时间取决于下列因素: 依据的算法选用何种策略; 问题的规模.例如求100以内还是1000以内的素数; 书写程序的语言.对于同一个算法,实现语言的级别越高,执

2、行效率就越低; 编译程序所产生的机器代码的质量; 机器执行指令的速度。,算法评价,一个算法是由控制结构(顺序、分支和循环三种)和原操作(指固有数据类型的操作)构成的,则算法时间取决于两者的综合效果。 为了便于比较同一问题的不同算法,通常的做法是,从算法中选取一种对于所研究的问题(或算法类型)来说是基本运算的原操作,以该基本操作重复执行的次数作为算法的时间度量。,算法评价,一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数f(n),算法的时间量度记作T(n)= O(f(n) 它表示问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐进时间复杂度,简称时间复杂度。

3、,算法评价,例如:在下列三个程序段中, x:=x+1 for i:=1 to n do x:=x+1; for j:=1 to n do for k:=1 to n do x:=x+1 含基本操作“x增1”的语句x:=x+1的频度分别为1,n和 n2 ,则这三个程序段的时间复杂度分别为O(1),O(n),O(n2),分别称为常量阶、线性阶和平方阶。,算法评价,算法还可能呈现的时间复杂度有:对数阶O(log n),指数阶O(2n)等。在n很大时, 不同数量级时间复杂度显然有O(1)O(log n)O(n)O(nlog n)O(n2) O(n3)O(2n),可以看出,在算法设计时,我们应该尽可能选

4、用多项式阶O(nk)的算法,而不希望用指数阶的算法。,算法评价,由于算法的时间复杂度考虑的只是对于问题规模n的增长率,则在难以计算基本操作执行次数(或语句频度)的情况下,只需求出它关于n的增长率或阶即可。例如,在下列程序段中:for i:=2 to n do for j:=2 to i-1 do x:=x+1 语句x:=x+1执行次数关于n的增长率为n2,它是语句频度表达式(n-1)(n-2)/2中增长最快的一项。,算法评价,类似于算法的时间复杂度,以空间复杂度作为算法所需存储空间的量度,记作S(n)=O(f(n) 其中n为问题的规模(或大小)。一个上机执行的程序除了需要存储空间来寄存本身所用

5、指令、常数、变量和输入数据外,也需要一些对数据进行操作的工作单元和存储一些为实现计算所需信息的辅助空间。,算法评价,评价一个数学模型有以下几个原则: 1.时间复杂度一个好的算法一般效率比较高。在竞赛中,试题常常会做一些算法运行时间上的限制。这就要求我们所建立的数学模型对应算法的效率一定要符合要求。这也是最重要的一个原则。,算法评价,2.空间复杂度出于计算机自身的限制,程序在运行时一般只被提供有限的内存空间。这也就要求我们建立模型时顾及到这一点。但对于模型对应的算法来说,并不是要求空间越低越好,只要不超过内存限制就可以了。,算法评价,3.编程复杂度相对而言,“编程复杂度”的要求要略低一些。但是在

6、竞赛中,如果建立的算法实现起来十分繁琐,自然不利于比赛。所以,在建立模型时(特别是在竞赛中)这点也要纳入考虑之中。,算法评价,一道题目可能对应几种不同思想的模型,就要根据评价模型的标准来衡量一下,确定一个模型作为分析方向。这时的评价标准除了上述的时间、空间、编程复杂度三个标准外,还要加上一个思维的复杂度。,算法评价,所谓思维的复杂度,是指思考所耗费的时间和精力。如果我们确定了一个模型作为分析的方向(没有考虑思维复杂度),从问题原型到该数学模型的建模过程却十分复杂,导致思维耗费时间长,精力多,那自然是不合算的。总的来说,对于多种数学模型的选择,我们遵循“边分析,边选择”的原则。,影响算法效率的因

7、素,问题的算法模型的建立 问题的数据结构选择,例题1:走迷宫问题(maze) 【题目描述】有一个n*n的迷宫,每个方格里都有着相应的数字。你从左上角出发,每次可以向上下左右四个方向最多移动k格,并且要求你每次到达的方格里的数字必须大于上一次所在方格的数字。现在要求你走过的方格的所有数之和最大,问这个最大和是多少。,例题1:走迷宫问题(maze),【题目描述】有一个n*n的迷宫,每个方格里都有着相应的数字。你从左上角出发,每次可以向上下左右四个方向最多移动k格,并且要求你每次到达的方格里的数字必须大于上一次所在方格的数字。现在要求你走过的方格的所有数之和最大,问这个最大和是多少。 【数据范围】1

8、 = n = 100 ,1 = k = n ,方格里的数最大不超过integer。 【输入文件】 maze.in。 第一行为 n 和 k,以下 n 行是一个 n * n 的矩阵。 【输出文件】 maze.out。 仅一个数,为求得的最大和。 【样例输入】 3 1 3 6 2 4 7 9 2 3 1 【样例输出】25,解法一,基于产生式系统的搜索算法,效率极低,为指数级别的算法。,解法二(动态规划模型一),我们首先很容易想到把矩阵拉成一条直线,然后按矩阵里的元素从小到大排序,并用no数组表示现在的元素在原矩阵中的位置。设fi表示前i个数中选取第I个数所能得到的最大和,则有: fi = Max f

9、j + ai 且aj ai,且现数列中元素j在原矩阵中可以达到现数列中的元素i在原矩阵中的位置。 易知所求答案为 Max fi (k = i = n)。( k 表示矩阵左上角元素在新数列中的位置) 此算法时间复杂度最坏 O(n4),空间复杂度 O(n2)。,解法三(规划模型二),因为题目中明确表示一次移动的两个存在大小关系,设路径为A(x1,y1),A(x2,y2)A(xl,yl),那么可以得到A(x1,y1)A(x2,y2)A(xl,yl),由此可以看出按照移动的步数划分阶段不会产生后效性,用f(l,x,y)表示在第l步移动到x,y步所能得到的最大和。状态转移: F(l,x,y)=maxf(

10、l-1,x1,y),f(l-1,x,y1)+Ax,y(abs(x1-x)=k ,abs(y1-y)=k) F(0,1,1)=A1,1 时间复杂度为o(L*n2*k)。空间复杂度 O(n3)。,解法四(规划模型三),我们用fi,j表示到达矩阵(i,j)位置时所能得到的最大和,由于题目对递增序列的要求,使得这道题目不用转换成一维数列就可以直接进行规划,规划方程为: fi,j = Max fi1,j1 + ai,j (ai1,j1 ai,j) 其中(i1,j1)表示从(i,j)通过允许的移动可以到达的位置,则所求答案即为Max fi,j (1 = i,j = n)。 此算法的时间复杂度 O(n*n*

11、k),空间复杂度 O(n2)。,解法五(图论模型),以迷宫的每个房间为点,如果(a,b)可以移动到(c,d),那么就从(a,b)引出一条有向边到(c,d),边上的权值为A(c,d),建立一张有向图,然后以A(1,1)点为源点求最长路。用SPFA实现,大概的时间复杂度为o(n2*k)。,不同数据结构对算法效率的影响,乘船问题:有N个人需要乘船,而每条船最多只能载两人,且必须同名或同姓。求最少需要多少条船。,问题分析,看到这道题,很多人都会想到图的数据结构:将N个人看作无向图的N个点,凡同名或同姓的人之间都连上边。 要满足用船最少的条件,就是需要尽量多的两人共乘一条船,表现在图中就是要用最少的边完

12、成对所有顶点的覆盖。这就正好对应了图论的典型问题:求最小边的覆盖。所用的算法为“求任意图最大匹配”的算法。,分析,使用“求任意图最大匹配”的算法比较复杂(要用到扩展交错树,对花的收缩等等),效率也不是很高。因此,我们必须寻找一个更简单高效的方法。首先,由于图中任两个连通分量都是相对独立的,也就是说任一条匹配边的两顶点,都只属于同一个连通分量。因此,我们可以对每个连通分量分别进行处理,而不会影响最终的结果。,采用图的数据结构得出的算法为:每次输出一条非桥的边,并从图中将边的两顶点删去。此算法的时间复杂度为O(n3)。 (寻找一条非桥边的复杂度为O(n2),寻找覆盖边操作的复杂度为O(n)),采用

13、树结构解决,首先,我们以连通分量中任一个顶点作为树根,然后我们来确定建树的方法: (1)找出与根结点i同姓的点j(j不在二叉树中)作为i的左儿子,再以j为树根建立子树。 (2)找出与根结点i同名的点k(k不在二叉树中)作为i的右儿子,再以k为树根建立子树。,我们还可以对需要船只s的下限进行估计:对于一个包含Pi个顶点的连通分量,其最小覆盖边数显然为Pi/2。若图中共有L个连通分量,则s=Pi/2(1=i=L)。然后,我们通过多次尝试,可得出一个猜想:实际需要的覆盖边数完全等于我们求出的下限Pi/2(1=i=L)。,两点间用实线表示同姓,虚线表示同名,结论及其证明,结论1:以连通分量中的任一点p

14、作为根结点的二叉树,必然能够包含连通分量中的所有顶点。 结论2:包含m个结点的二叉树Tm,只需要船的数量为boatm=m/2(mN)。,如何证明?采用数学归纳法(见文本“论文”),如何输出具体的乘船方案,proc try(father:integer;var root:integer;var rest:byte); 输出root为树根的子树的乘船方案, father=0表示root是其父亲的左儿子, father=1表示root是其父亲的右儿子, rest表示输出子树的乘船方案后,是否还剩下一个根结点未乘船,begin visitroot:=true; 标记root已访问 找到一个与root同

15、姓且未访问的结点j; if jn+1 then try(0,j,lrest); 找到一个与root同姓且未访问的结点k; if kn+1 then try(1,k,rrest);,if (lrest=1) xor (rrest=1) then begin 判断root是否只有一个儿子,情况一 if lrest=1 then print(lrest,root) else print(rrest,root); rest:=0; end else,if (lrest=1) and (rrest=1) then begin 判断root是否有两个儿子 if father=0 then begin pr

16、int(rrest,root);root:=j; 情况二end else beginprint(lrest,root);root:=k; 情况三 End; rest:=1;end else rest:=1; end;,这只是输出一棵二叉树的乘船方案的算法,要输出所有人的乘船方案,我们还需再加一层循环,用于寻找各棵二叉树的根结点,但由于每个点都只会访问一次,寻找其左右儿子各需进行一次循环,所以算法的时间复杂度为O(n2)。,分治思想,分治(divide-and-conquer)就是“分而治之”的意思,其实质就是将原问题分成n个规模较小而结构与原问题相似的子问题;然后递归地解这些子问题,最后合并其

17、结果就得到原问题的解。其三个步骤如下; 分解(Divide):将原问题分成一系列子问题。 解决(Conquer):递归地解各子问题。若子问题足够小,则可直接求解。 合并(combine);将子问题的结果合并成原问题的解。,例题分析1 0-1序列,考虑这样一个序列”110100100010000”就是”1” + ”10”+”100”+”1000”+要求求出第I位是0 还是1。 Input: 第一行:N,测试点的个数;(N 0); Output: 对每个测试点输出0 或 1,每行一个数; Sample Input: (bit.in) 3 1 2 3 Sample Output: (bit.out)

18、 1 1 0,电缆老板(MASTER),某地区即将举行区域程序设计比赛,竞赛委员会已经成立并决定举行一次最公平的竞赛,他们决定利用星形拓扑结构来连接每个竞赛者的电脑-也即连接这些电脑到一个中心HUB上;为了达到真正的公平竞赛目的,竞赛委员会主任下令要求:每个竞赛电脑连接到中心HUB的电缆必须是一样长的。 竞赛委员会联系了一个本地的电缆老板,要求老板为他们提供一定量的相同长度的电缆,而且要求电缆长度越长越好。通过调查,电缆老板知道仓库中每根电缆的长度(精确到厘米),而且他可以以厘米的精度剪断电缆,但确不知道他能为竞赛委员会提供的每根电缆的最大长度是多少?,你的任务就是:编程求出每根电缆的最大可能

19、的长度。 输入:第1行,2个整数N和K,N是仓库中的电缆条数,K是竞赛委员会要求的电缆条数。其中1N1000, 1K10000。第2N+1行,每行为仓库中的一条电缆的长度,单位为米。 输出: 仅1行,为提供给竞赛委员的电缆最大长度(精确到小数点两位) 输入输出示例: MASTERIN MASTEROUT 4 11 2.00 8.02 7.43 4.57 5.39,例题3:图形中点的个数,给定平面上N个图形(矩形或圆)以及M个点后,请你求出每个点在多少个矩形或圆内部(这里假设矩形的边都平行于坐标轴)。 注意:当某点在一个图形的边界上时,我们认为该点不在这个图形的内部,分析,原始的解决方案:就是两

20、两都判一次。 优化:就是先将点按x排序。 如果图形是矩形,那就先二分查找在x1, x2范围内的那一段,对于段内的每一个点只用看看y在不在范围内就可以了。 如果图形是圆,那就先二分查找在x-r, x+r范围内的那一段,对于段内的每一个点再看看到圆心的距离。 这样程序的最坏效率是O(lgM*N*M),例题4:消除隐藏线,在计算机辅助设计(CAD)中,有一个经典问题:消除隐藏线(被其它图形遮住的线段)。你需要设计一个软件,帮助建筑师绘制城市的侧视轮廓图。为了方便处理,限定所有的建筑物都是矩形的,而且全部建立在同一水平面上。每个建筑物用一个三元组表示(Li,Hi,Ri)其中Li和Ri分别是建筑物i 的

21、左右边缘坐标,Hi是建筑物i的高度。,下面左图中的建筑物分别用如下三元组表示:(1,11,5),(2,6,7),(3,13,9),(12,7,16),(14,3 ,25),(19,18,22),(23,13,29),(24,4,28),下面图中的城市侧视轮廓线用如下的序列表示:(1,11,3,13,9,0,12,7,16,3,19,18,22,3,23,13,29,0),分析,本题其实是矩形覆盖问题的特殊情形固定了矩形的下边界。本题可以使用矩形切割或者离散化加上线段树解决,但是前者的时间复杂度在最坏情况下可能达到O(n3),而后者的编程实现比较复杂。,要求n个矩形的轮廓,先将这n个矩形分成两个

22、大小相等的部分,分别求其轮廓,然后再将这两个轮廓合并。 规模为1的问题可以直接解决。具体来说,如果这个矩形的三元组表示为(L,H,R),那么其轮廓为(L,H,R,0)。,对于规模为k的问题,假设得到了两个规模为k/2的轮廓,分别为A和B,我们如何得到合并后的轮廓C?首先,容易证明轮廓C的每一个横坐标,都来源于轮廓A和B的横坐标,而不会产生新的坐标值。因此,我们只需计算A和B中所有涉及到的横坐标在C中的高度。,由于轮廓C中的横坐标值要求有序,我们可以仿照归并排序的方法,用两个指针扫描轮廓A和B。具体的方法是,设指针i指向轮廓A的当前横坐标,指针j指向轮廓B的当前横坐标。如果指针i指向的横坐标较小

23、,那么将这一横坐标加入到C中,且在C中的高度为A中第i个横坐标对应的高度与B中第j-1个横坐标对应的高度的最大值。,然后将指针i向后移一位;指针j指向的横坐标较小的情况则类似处理。如果两个指针指向的横坐标相同,此时只需将这一横坐标加入到C中一次,且高度为两指针指向高度的最大值,然后将两指针同时向后移一位。最后,需要扫描一遍轮廓C,将相邻的高度相同的横坐标合并。,分析时间复杂度,T(n)=O(nlogn)。空间方面,由于递归的层数为O(logn),每一层需要保存O(n)的空间,所以总的空间复杂度为O(nlogn)。,L-Gap子串问题,如果一个字串形如UVU,U非空,且V恰好有L个字符,我们就称

24、这种UVU形式的字串是一个L-Gap串。例如, abcbabc是 1-Gap 字串, xyxyxyxyxy 既可以是一个 2-Gap字串,也可以是一个6-Gap字串,但它不是一个10-Gap字串 (因为 U 必须非空)。 现在的问题时,给定一个字串s和一个正整数g, 请你在s串中找出所有的g-Gap子串,并输出所有的g-Gap子串总数。规定s串仅由小写字母组成,且其长度不超过50,000。 输入:Input 第一行为一个数字 t(1=t=10),表示测试点的个数 。以后的t行,每行有一个数字g(1=g=10) 和一个字串 s。 输出: 对于每一组数据,输出该组数据中所包含的 g-Gap 子串的数目。 示例: 输入: 输出: 2 7 1 bbaabaaaaa 1 5 abxxxxxab,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 学术论文 > 大学论文

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报