- 1、本文档共5页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
算法作业:
LCS 问 题
作业要求:设计一个算法求出两个序列的所有LCS,分析最坏情况,用“会计方法”证明利用b[i][j]求出所有LCS的算法在最坏情况下时间复杂度为
算法思路: 根据最长公共子序列问题的性质,即经过分解后的子问题具有高度重复性,并且具有最优子结构性质,采用动态规划法求解问题。设X={x1, x2, … , xn}, Y={y1, y2, … , ym}, 首先引入二维数组C[i][j]记录Xi和Yj的LCS的长度,定义C[i][j]如下: 为了构造出LCS,还需要使用一个二维数组b[m][n],b[i][j]记录C[i][j]是通过哪个子问题的值求得的,以决定搜索的方向,欲求出所有的LCS,定义数组b如下:设1-对角线方向;2-向上;3-向左;4-向上或向左若X[i]=Y[j],b[i][j] = 1,若C[i-1][j]i][j-1], 则b[i][j] = 2,若C[i-1][j][i][j-1], 则b[i][j] = 3,若C[i-1][j]=[i][j-1], 则b[i][j] = 4,根据以上辅助数组C和b的定义,算法首先需要求出这两个数组, C[m][n]中记录的最长公共子序列的长度,b中记录了查找子序列元素的搜索方向。 利用C和b的信息,Find_All_LCS可以采用回溯法求出所有的LCS。基本思路如下:使用一个辅助数组记录每次调用Find_All_LCS得到的LCS中的元素,每次递归调用一次Find_All_LCS,进入一个新的执行层,首先要判断当前处理的两个子序列长度是否大于等于0 ,若不满足,则该层的递归结束,返回上一层;然后再判断当前得到的子序列是否等于数组C中求出的最长公共子序列长度,若等于,则说明算法执行到此已经得到一个LCS,按序输出;若不等于,此时根据数组b中记录的搜索方向继续搜索,特别要说明的是,当b[i][j]=4时,即要向上或向左,需要对这两个方向分别调用Find_All_LCS,保证沿着这两个方向上LCS元素不被漏掉,都可以搜索到;若b[i][j]=1,即沿对角线方向搜索前进时,此时元素X[i]为LCS中的元素,存放至辅助数组中去,同时将当前已经求得的LCS长度增1,当递归调用Find_All_LCS从b[i][j]=1处时,需要回溯一步,搜索其它路径上可能为LCS中的元素。当所有的可能路径都已经搜索完,算法结束。 对于某些情况会输出重复的LCS,这是因为算法在沿不同路径搜索时可能会出现相同的LCS序列。
时间复杂度分析 由上述对Find_All_LCS 算法的分析可知,求出所有的LCS实际上是根据搜索的方向信息遍历所有的路径找出满足条件的元素集合。因此,除求解辅助数组C和b所用的O(mn+m+n)的执行时间外,Find_All_LCS的时间复杂度取决于所遍历路径数。而路径数是由搜索方向决定的。显然算法在最好的情况下,即m=n并且b中所有的值都指示沿着对角线方向搜索,时间复杂度为O(n). 相反,当X和Y序列不存在公共子序列时为算法的最坏情况,此时C中所有值都等于0,数组b中所有的值都指示要分别沿两个不同的方向(向左或向上)搜索,这种情况下每处理一次X[i],Y[j]时总是要沿两个方向分别调用Find_All_LCS,遇到i=0或j=0时返回,直到搜索完所有的可能路径才结束,最坏情况下的搜索矩阵如下图所示:
由此可知,要确定最坏情况的时间复杂度,就是要计算出从点到i=0或j=0(除=(0,0)外)的所有路径。求解转化为组合数学中的路径数问题。建立一个直角坐标系如上图中所示,对于坐标系中的点可以沿向上或向左两个方向前进,设点,轴上的坐标点,轴上的系列坐标点,其中.
因为是搜索路径的边界上的点,点不能直接到达点,点也不能直接到达,所以点到和的路径数等价于到点和点的路径数,又因为点到路径数为,设总路径数为,则有
根据组合数学的基本知识可得:
[注]:参考卢开澄编著的《组合数学(第3版)》P34-P38
最坏情况下算法搜索的所有路径为从S到和的所有路径数,因此算法在最坏情况下的时间复杂度为.
算法实现
/*文件名:FindLongestCommonSequence.cpp
说明:求出两个序列中所有的最长公共子序列
日期:2005/10/12*/
#include iostream
#include string.h
#define MAXSIZE 100
using namespace std;
int C[MAXSIZE][MAXSIZE] ; //记录序列X和Y的LCS的长度
int B[MAXSIZE][MAXSIZE
文档评论(0)