乐飞-算法分析与设计学习笔记

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

2.1 递归的概念
递归,也就是在一个算法中,自己调用自己以实现问题的解决,这样的算法 就是递归算法。按照这种思想设计的函数就是递归函数,递归函数设计比较快 捷,一旦确定了递归的公式,就可以很快设计出实现递归的函数,递归的细节
和实现递归的过程比较难以模拟,只要递归的公式正确,可以把实现递归的函
数理解成一个设置了初始条件的自动执行的函数,不必深究细节。 可以用递归技术解决的问题主要是数据结构本身或者数学问题是递归定义的, 或者可以按照递归技术解决的问题。递归的实例,比如阶乘问题,斐波那契函 数,排列问题,整数划分问题,以及经典的汉诺塔问题。
查找树如下:
2.4大整数乘法
算。 复杂的数值运算中数值的长度超出了计算机硬件所能表达的范围,需要用软件的方法进行大整数的计
设X和Y是n为二进制数,如果直接进行二进制的乘法运算,步骤太多,效率一般。提高效率务必减少乘法次数。 将X和Y都分成两段
2.5 Strassen矩阵乘法
2.6 棋盘覆盖
该特殊棋盘中需要图示 的五个L型骨牌进行覆 盖才能满足要寻求
《算法设计与分析》读书报告
武乐飞
2.递归与分治策略
2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 递归的概念 分治法的基本思想 二分搜索技术 大整数的乘法 Strassen矩阵乘法 棋盘覆盖 合并排序 快速排序 线性时间选择
3.动态规划
3.1 3.2 3.3 3.4 3.5 3.6 矩阵连乘问题 动态规划算法的基本要素 最长公共子序列 凸多边形最优三角划分 多边形游戏 图像压缩
2.动态规划
动态规划算法与分治法类似,其基本思想也是将待求问题分解成若干个小问题,先求解子问题,然后 从这些子问题中的解中得到原问题的解,与分治法不同的是,动态规划中的子问题不是相互独立的而是存 在着某种联系的,诸子问题的求解也是有先后顺序的。动态规划问题有两个性质:一是具有最优子结构性 质,就是当原问题得到最优解时,其子问题也必定是最优解;二是具有子问题重叠性质,如上面所说,动 态规划中的诸多子问题都具有某种联系,包括子问题的重叠,在计算过程中会出现重复解决某些子问题的 现象。在实际运用中,为了解决子问题重叠问题,一般会设置一个记录表,记录已经解决的子问题的解, 当需要求解下一个子问题是,先在记录表中对照,如已经有相关记录,则不用进行重复计算。以上就是动 态规划的基本思想。 一般解决动态规划问题的基本步骤如下: 找出最优解的性质,并刻画其数据结构; 递归地定义最优值; 以自底向上的方式计算出最优值; 根据计算得到最优值得到的信息,构造最优解。
3.1 矩阵连乘问题
3.1 矩阵连乘问题
首先计算出m[i][i],i=1,2,3,,紧接着计算m[i][i+1] i=1,2,3,,(矩阵长度为2), m[i][i+2] i=1,2,3,,(矩 阵长度为3),以此类推,其中计算m[i][j]时需要用到 m[i][k]和m[k+1][j]的结果。
2.递归与分治策略
问题的规模决定着用计算机求解该问题所需要的时间。问题的规模越大,使 用计算机解决该问题所用的时间也就越多。分治法的思想是将一个规模比较大 的,使用常规方法处理导致效率比较低的问题,按照一定的规律分解成解决起
来比较容易的小问题,各个击破,分而治之。如果将原问题分解得到的小问题
都可以使用常规方法解决且效率可观则证明分治法是可行的。按照分治的思想 获得的小规模问题是原问题的精简版,可以使用递归的方法进行处理,在实际 应用中分治法和递归是交叉使用,你中有我,我中有你的。
算法需要输入四个参数,tr:棋盘最左上角方格的行号; tc:棋盘最左上角方格的列号; dr:特殊方格所在的行号; dc:特殊方格所在的列号.
设T(k)是本算法的运行所需要的时间,根据分治 法总式可得,
2.7 合并排序
合并排序是用分治策略对n个元素进行排序,属于典型的分治策略的应用,基本思想为将待排序的集 合分成两个大小基本相同的子集合,在进一步分别对子集合进行排序,然后将排好序的诸子集合回溯合并, 最终实现对原集合的排序。
2.6 棋盘覆盖
特殊方格必位于4个较小子棋盘之一中,其余3个子棋盘中无特殊方格。为了将这3个无特殊方格 的子棋盘转化为特殊棋盘,可以用一个L型骨牌覆盖这3个较小棋盘的会合处,如 下图所示,从而将 原问题转化为4个较小规模的棋盘覆盖问题。递归地使用这种分割,直至棋盘简化为棋盘1×1。 一开始知道棋盘的最左上角的坐标和特殊方格的坐标,通过比较 坐标值的大小可以判定特殊方格位于哪个区域,就对那部分区域进行 递归,直到剩余一个方格,就算特殊方格不在某区域区域,也要对该 区域用L行骨牌进行覆盖。 以一个二维数组board表示方格,若某方格被骨牌覆盖,则将代表 该方格的board[i][j]的值设置为L型骨牌号,代码实现如下:
一个分治法将规模为n的原问题分解为k个规模为n/m的子问题,为方便起见,设分解阙值n0=1,解子问题用时一个 单位时间,将子问题合并为原问题的merge算法用f(n)个单位时间,时间复杂度如下:
递归方程的解为:
以上为分治法时间复杂的总式,后面计算常常用到!
2.3 二分搜索技术
也就是折半查找,待查找元素已经排序,设置左右指针和中间指针, 在下面查找16这个数字,指针变化如下: 过程比较清晰了,代码如下:
2.2分治基本思想
将原规模为n的问题分解为k个规模较小的子问题,这些问题相互独立且与 原问题相同。
|P|为问题P的规模,n0是一个界限值,表示对原问题的分解已 经足够小,不必在进行分解,adhoc(P)属于基本子算法,用于 解分解后的问题,merge(y1,y2,,,,,)是用来合并已经求出的小 问题,回溯合并为P的解。
2.9 线性时间选择
2.9 线性时间选择
基于中位数的线性时间选择的时间复杂度的分析:对n个元素进行调用算法select(),找到中位数的中位数需 要T(n/5)的时间,上面已经证明子数组至多有3/4n个元素,子数组调用select使用了T(3/4n)的时间,得到关 于T(n)的递归式子:
显然T(n)=O(n).
2.9 线性时间选择
问题定义:给定线性序集中n个元素和其中一个整数k(1<=k<=n),要求找出这n个元素中第k小的元素,即 顺序排列的n个元素中的第k个元素。如k=1时就是查找最小的元素,k=n时就是最大的元素,中位数是 k=(n+1)/2。 下面提供一个一般选择问题的分治算法randomizedSelect(),代码如下: 其中的randomizedPartiton()是随机 选择基准值的改良的快速排序中的划 分函数,以求达到中值划分。
整数划分问题:
将正整数n表示成一系列正整数之和:n=m1+m2+m3+m4…………为n的一个划分。其中最大加不超过m,则称其为n的一 个m划分,即q(n,m)。分析如下: 当n=1时,一个划分,1; 当m=1时,一个划分,加数都是1; 当n=m时,第一种情况:划分中包含n的情况,即{n}; 第二种情况:划分中不包含n的情况,即最大加数小于n,即q(n,n-1); 即1+ q(n,n-1) 当n<m时,由于划分中不可能出现负数,相当于q(n,n); 当n>m时,第一种情况:包含m。即{m,{其余加数}},即q(n-m,m); 第二种情况:不包含m的情况,即所有加数都小于m-1,即q(n,m-1) 即q(n,m)= q(n-m,m)+ q(n,m-1). 综上所述:
基于中位数的线性时间选择算法思想如下: 将集合分成⌈ (n/5) ⌉个组,即每个组中的元素都为5,最后一组元素数量为n mod 5 ,最后一组不算数; 对每个组分别使用任意排序,如冒泡排序,并寻找出每个组的中位数; 将每个组的中位数依次替换掉给定序列的前n个元素; 在序列前n和选定的各组中位数中再求其中位数,也就是中位数的中位数,记为x; 对整个序列使用快排算法中的划分函数partition,得到索引i,将整个序列分为两部分,第i个元素属于前半部分; 如果i=k,则返回x;如果i<k,则对低分区重复上述过程;如果i>k,对高分区重复上述过程。 基于中位数的线性时间选择算法中用到的基准 数值至关重要,关系着算法是否能在线性时间内完 成任务,按照上述步骤选择出的中位数能够将原序 列尽可能实现均分,两个子数组的大小不会差别太 大。假设所有元素互不相同,找出的基准数x都至 少比3⌊(n-5)/10⌋个元素大,因为每一组中都有2个 元素小于本组中位数,x在所有中位数中处于(n2)/10的位置,所以找出的基准数x都至少比3⌊(n5)/10⌋个元素大,同理该基准值比至少比3⌊(n5)/10⌋个元素小,所以按照这个基准划分的子数组 都会至少缩短四分之一,子数组至多不会超过原数 组的四分之三。
对数组{8,4,5,7,1,3,6,2}进行排序的过程如下: 按照上述思想,合并排序的算法可以递归地定 义如下:
算法将排好序的两个子数组移动到新数组b中, 在通过copy函数复制回数组a中.此时的算法复 杂度为O(nlogn).
2.7 合并排序
上述的思想中涉及到递归技术的使用,还可以改进,消除算法中的递归,在递归的算法中,要做的就是 一直递归到当前集合中只有一个元素,然后进行合并以及copy(),改进的方法就是实现对集合a中的元素进 行两两配对,构成n/2组长度为2的子数组,进一步排序合并成为长度为4的子数组,以此类推,直到a中元素 全部完成排序。 改进后的算法由三个函数组成:mergeSort()、mergePass()和merge()。 首先看merge()函数: 合并算法开始, merge()函数接收的子数组的长度 只有1,也就是从一开始就确保c[l:m]和c[m+l:r]是有序 的,
3.2 动态Biblioteka Baidu划算法的基本要素
通常递推出问题的结构后,假设在 原问题最优解是子问题不会最优解, 也就是子问题存在更加优良的解, 那么与原问题是最优解冲突。
通常使用一个记录表记录已经计算 的子问题,当后续的其他子问题需 要或者相同的子问题时,只需要简 单的查一下就ok!
归并排序的时间复杂度为O(nlogn),即:
2.8 快速排序
快速排序算法是采用分治策略的排序算法,按照以下的步 骤进行排序: 分解:选择一个元素a[p]为基准元素(一般选择首元素), 一趟排序之后,集合被分为三段,a[p:q-1],a[q]和 a[q+1:r],使得a[p:q-1]中的元素均小于a[q],而a[q+1:r] 中的元素均大于a[q]; 递归:对a[p:q-1]和a[q+1:r]中元素递归求解上述步骤; 合并:上述步骤是就地进行的,不需要进行多余的合并 步骤。 快速排序的算法代买如下:
阶乘问题:
阶乘函数的定义是递归的
很显然,使用递归解决,算法如下:
递归的实现算法,很好理解,也很好地体现了函数本身 调用本身,即递归调用。
排列问题:
给一个集合R,个数为n,实现输出集合元素的全排列,共有n!种排列。归纳 定义如下: 当n=1时,perm(R)=(r),就一个元素, 当n>1时,perm(R)由(r1) perm(R1)……… (rn) perm(Rn),其中 Rn={R- rn},也就是,分别固定一个元素在首位,求其余元素的全排列,求其余元 素的全排列时,同样先固定一个元素在首位,以此类推,直到只有一个元素,不再 往深层次递归,然后回溯,求出所有排列。实现如右图:
2.8 快速排序
qSort()中partition()函数的功能是返回一趟排序后的基准值(把待排序集合分为左右两部分),进行下次 递归, partition()函数实现如下: 完成一趟排序后,返回a[j]的坐 标作为下一次递归的基准值a[p],直 到完成全部集合元素的排序。
通过随机选择(p和r)的值能接近 最好的情况
对子数组进行排 序,子数组的长 度依次是1,2,4,8, 等等。
2.7 合并排序
在看mergePass()函数,这个函数调用merge()函数,实现排好序的相邻子数组 的合并,而排序是由merge()函数接受长度为1的子数组开始的。
mergeSort()函数,负责调用mergePass()函数,最终实现 原问题解决
相关文档
最新文档