阅读材料遗传算法.docx
- 文档编号:10817201
- 上传时间:2023-02-23
- 格式:DOCX
- 页数:38
- 大小:217.49KB
阅读材料遗传算法.docx
《阅读材料遗传算法.docx》由会员分享,可在线阅读,更多相关《阅读材料遗传算法.docx(38页珍藏版)》请在冰豆网上搜索。
阅读材料遗传算法
阅读材料——算法研究与图灵奖
图灵奖设立于1966年,是美国计算机协会ACM在计算机科学与技术方面所授予的最高奖项,被称为计算机界的诺贝尔奖,主要授予在计算机领域做出突出贡献的个人。
表1.2是历届图灵奖获得者的简要介绍。
表1.2历届图灵奖获得者的简要介绍
年份
姓名
获奖原因
1966年
AlanJ.Perlis
高级程序设计技巧,编译器构造
1967年
MauriceV.Wilkes
内部存储程序,程序库
1968年
RichardHamming
数值方法,自动编码系统,错误检测和错误纠正码
1969年
MarvinMinsky
人工智能
1970年
JamesH.Wilkinson
数值分析,线性代数,“倒退”错误分析
1971年
JohnMcCarthy
人工智能
1972年
EdsgerDijkstra
现代编程语言的主要贡献者之一
1973年
CharlesW.Bachman
数据库技术
1974年
DonaldE.Knuth
算法分析和编程语言的设计
1975年
AllenNewell,HerbertA.Simon
人工智能,人类认知心理学和列表处理
1976年
MichaelO.Rabin,DanaS.Scott
非确定性自动机
1977年
JohnBackus
高级编程系统,程序设计语言规范的形式化定义
1978年
RobertW.Floyd
设计高效可靠软件的方法学
1979年
KennethE.Iverson
程序设计语言和数学符号,互动系统的设计
1980年
AntonyR.Hoare
程序设计语言的定义与设计
1981年
EdgarF.Codd
数据库系统,尤其是关系型数据库
1982年
StephenA.Cook
计算复杂性
1983年
KenThompson,DennisM.Ritchie
通用的操作系统理论,UNIX操作系统
1984年
NiklausWirth
计算机语言设计
1985年
RichardM.Karp
算法理论,尤其是NP完全性理论
1986年
JohnHopcroft,RobertTarjan
算法和数据结构的设计与分析
1987年
JohnCocke
编译理论,大型系统的体系结构,精简指令集
1988年
IvanSutherland
计算机图形学
1989年
WilliamKahan
数值分析
1990年
FernandoJ.Corbató
大型多功能、可实现时间和资源共享的计算系统
1991年
RobinMilner
可计算的函数逻辑(LCF)、ML和并行理论(CCS)
1992年
ButlerW.Lampson
分布式,个人计算环境
1993年
JurisHartmanis,RichardE.Stearns
计算复杂性理论
1994年
EdwardFeigenbaum,RajReddy
大规模人工智能系统
1995年
ManuelBlum
计算复杂性理论,密码学和程序校验
1996年
AmirPnueli
时序逻辑,程序与系统验证
1997年
DouglasEngelbart
互动计算
1998年
JamesGray
数据库与事务处理
1999年
FrederickP.Brooks
计算机体系结构,操作系统,软件工程
2000年
AndrewChi-ChihYao
伪随机数生成,密码学与通信复杂度
2001年
Ole-JohanDahl,KristenNygaard
面向对象编程
2002年
Ronald L. Rivest,Adi Shamir,
Leonard M. Adleman
公钥密码学
2003年
AlanKay
面向对象编程
2004年
VintonG.Cerf,RobertE.Kahn
TCP/IP协议
2005年
PeterNaur
ALGOL60,BNF范式
2006年
FrancesAllen
优化编译器技术的理论和实践,并行转换
2007年
EdmundClarke,AllenEmerson,
JosephSifakis
模型检测技术
2008年
BarbaraLiskov
让计算机软件更加可靠、安全和更具一致性
2009年
CharlesThacker
第一台现代个人计算机Alto的先驱性设计与实现
2010年
LeslieValiant
PAC学习,代数计算,并行与分布式计算
算法在计算机科学领域无处不在,很多图灵奖获得者在算法设计及复杂性分析方面都有所建树。
例如,Hoare在26岁就发明了闻名于世的快速排序算法;Ronald、Shamir和Adleman发明了国际上最具影响力的公钥密码算法RSA;数据结构与算法领域的主要内容都是出自Knuth编著的《程序设计的艺术》;Floyd发明了求解多源点最短路径的Floyd算法;Karp给出了证明NP完全问题的方法,在网络流和组合优化问题领域都发明了许多高效算法;Hopcroft和他的学生Tarjan由于在数据结构和算法方面的众多创造性贡献而共同获此殊荣,在业界传为美谈;姚期智(Chi-ChihYao)发明了伪随机数的生成算法,在加密/解密方面也发现了许多有价值的算法;PeterNaur创建了语法描述中广泛使用的BNF范式;Sutherland发明的图形图像算法改善了屏幕刷新的文件显示,以及对图形对象的递归扫描;Cook的开创性文章揭开了计算复杂性中NP完全性的研究;Rabin与Scott合作撰写的研究论文提出了非确定性机器的观点;Dijkstra发明了单源点的最短路径算法Dijkstra算法,以及程序并发执行过程中进程同步的解决方法;Wilkinson在数值线性代数方面发现很多有意义的算法;Blum发现了著名的算法设计技术——分支限界法;等等。
阅读材料——算法的实验分析
渐进分析是一种数学方法,渐进分析技术能够在数量级上对算法进行精确度量。
但是,数学不是万能的,实际上,许多貌似简单的算法很难用数学的精确性和严格性来分析,尤其分析平均情况。
算法的实验分析(experimentanalysis)是一种事后计算的方法,通常需要将算法转换为对应的程序并上机运行。
例如,为了测算起泡排序算法在实际运行过程中的比较次数和移动次数,可以设置两个计数器count1和count2,在比较语句执行前将计数器count1加1,在交换语句执行后将计数器count2加3(因为交换操作需要用三条赋值语句实现)。
程序如下:
voidBubbleSort(intr[],intn)
{
intcount1=0,count2=0;//count1和count2记载比较次数和移动次数
intbound,exchange=n-1;//第一趟起泡排序的区间是[0,n-1]
while(exchange!
=0)//当上一趟排序有记录交换时
{
bound=exchange;exchange=0;
for(intj=0;j if(++count1&&r[j]>r[j+1])//注意不能写作count1++ { inttemp=r[j];r[j]=r[j+1];r[j+1]=temp; count2=count2+3;//1次交换是3次移动操作 exchange=j;//记载每一次记录交换的位置 } } cout<<"比较次数是"< cout<<"移动次数是"< } 下面给出算法实验分析的一般步骤: (1)明确实验目的。 在对算法做实验分析时,可能会有不同的目的,实验的设计依赖于实验者要寻求什么答案。 例如,检验算法效率理论分析的正确性,比较相同问题的不同算法或相同算法的不同实现间的效率,等等。 (2)决定度量算法效率的方法。 一般来说,有以下两种度量方法: ①计数法。 在算法中的适当位置插入一些计数器,来度量算法中基本语句(或某些关键语句)的执行次数。 ②计时法。 度量某个特定程序段的运行时间,可以在程序段的开始处和结束处查询系统时间,然后计算这两个时间的差。 需要注意的是,在分时系统中,所记录的时间很可能包含了CPU运行其他程序的时间(例如系统程序),而实验应该记录的是专门用于执行特定程序段的时间。 例如,在UNIX中将这个时间称为用户时间,time命令可以完成这个功能。 (3)生成实验数据。 对于某些经典算法(例如TSP问题),研究人员已经制定了一系列输入实例作为测试的基准,但大多数情况下,需要实验人员自己确定实验的输入实例。 (4)对输入实例运行算法对应的程序,记录得到的实验数据,通常用表格或者散点图记录实验数据。 以表格呈现实验数据的优点是直观、清晰,可以方便地对数据进行计算。 散点图在笛卡儿坐标系中用点将数据标出,其优点是可以确定算法的效率类型。 表2.1是对某算法采用计数法得到的实验数据,图2.5给出了一个散点图的示例。 表2.1表格法记录实验数据 规模 1000 2000 3000 4000 5000 6000 7000 8000 9000 次数 11,966 24,303 39,992 53,010 67,272 78,692 91,274 113,063 129,799 (5)分析得到的实验数据。 根据实验得到的数据,结合实验目的,对实验结果进行分析,并根据实验结果不断调整实验的输入实例,经过对比分析,得出具体算法效率的有关结论。 算法的渐进分析和实验分析的基本区别是: 渐进分析不依赖于特定输入,缺点是适用性不强,尤其对算法做平均性能分析时;实验分析能够适用于任何算法,缺点是其结论依赖于实验中使用的特定输入实例和特定的计算机系统。 实际应用中,可以采用渐进分析和实验分析相结合的方式来分析算法,首先在理论上描述算法的运行效率,然后针对特定计算机或程序根据实验分析确定其中一些必要的参数。 阅读材料——KMP算法中next值的计算 【问题】设模式的长度为m,用蛮力法求解KMP算法中的next值时,T[0]可直接给出,一般情况下,计算next[j](1≤j≤m-1)需要在T[0]…T[j-1]中分别取长度为j-1、…、2、1的真前缀和真后缀并比较是否相等,最坏情况下的时间代价是: 请改进蛮力法求解KMP算法中next值的算法,使其时间代价为O(m)。 【想法】模式T[0]T[1]…T[m-1]中的每一个字符T[j]都对应一个k值,用next[j]表示T[j]对应的k值(0≤j≤m-1),其定义如下: 因为T[0]既没有真前缀也没有真后缀,因此next[0]=-1。 假设已经计算出next[0],next[1],…,next[j],如何计算next[j+1]呢? 设k=next[j],则T[0]…T[k-1]=T[j-k]…T[j-1],这意味着T[0]…T[k-1]是T[0]…T[j-1]的真前缀,同时T[j-k]…T[j-1]是T[0]…T[j-1]的真后缀。 为了计算next[j+1],比较T[k]和T[j],可能出现两种情况: (1)T[k]=T[j]: 说明T[0]~T[k-1]T[k]=T[j-k]~T[j-1]T[j],如图3.16所示。 由next值的定义,next[j+1]=k+1; (2)T[k]≠T[j]: 此时要找出T[0]…T[j-1]的真前缀和真后缀相等的第2大子串,由于T[0]…T[j-1]的真前缀和真后缀相等的最大子串是T[0]…T[k-1],而next[k]的值为T[0]…T[k-1]的真前缀和真后缀相等的最大子串的长度,则T[0]…T[next[k]-1]即为T[0]…T[j-1]的真前缀和真后缀相等的第2大子串,如图3.17所示。 令k=next[k],再比较T[k]和T[j],此时仍会出现两种情况,当T[k]=T[j]时,与情况 (1)类似,此时,next[j+1]=k+1;当T[k]≠T[j]时,与情况 (2)类似,再找出T[0]…T[k-1]的真前缀和真后缀相等的最大子串,重复 (2)的过程,直到T[k]=T[j],或next[k]=-1,说明T[0]…T[j-1]不存在真前缀和真后缀相等的子串,此时,next[j+1]=0。 例如,模式T="abaababc"的next值计算如下: j=0时,next[0]=-1 j=1时,k=next[0]=-1,next[1]=0 j=2时,k=next[1]=0,T[0]≠T[1];k=next[k]=next[0]=-1,next[2]=0 j=3时,k=next[2]=0,T[0]=T[2],next[3]=k+1=0+1=1 j=4时,k=next[3]=1,T[1]≠T[3];k=next[k]=next[1]=0,T[0]=T[3],next[4]=k+1=1 j=5时,k=next[4]=1,T[1]=T[4],next[5]=k+1=1+1=2 j=6时,k=next[5]=2,T[2]=T[5],next[6]=k+1=2+1=3 j=7时,k=next[6]=3,T[3]≠T[6];k=next[k]=next[3]=1,T[1]=T[6],next[7]=k+1=2 【算法实现】基于以上想法的求next值的算法用C++语言描述如下: voidGetNext(charT[],intnext[]) { intj=0,k=-1; next[0]=-1; while(T[j]! ='\0')//直到字符串末尾 { if(k==-1){//无相同子串 next[++j]=0;k=0; } elseif(T[j]==T[k]){//确定next[j+1]的值 k++;//相等子串长度加1 next[++j]=k; } elsek=next[k];//取T[0]…T[j]的下一个相等子串的长度 } } 【算法分析】算法GetNext只需将模式扫描一遍,设模式的长度为m,则算法的时间复杂性为O(m)。 阅读材料——递归函数的执行过程 由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。 反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易直接求解,这自然导致递归过程的产生。 分治与递归就像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效的算法。 递归(recursion)就是子程序(或函数)直接调用自己或通过一系列调用语句间接调用自己,是一种描述问题和解决问题的基本方法。 递归必须具备以下两个基本要素,才能在有限次计算后得出结果。 (1)边界条件: 确定递归到何时终止,也称为递归出口; (2)递归模式: 大问题是如何分解为小问题的,也称为递归体。 由于递归程序比较简洁,而且调用函数和被调用函数是同一个函数,很多人费解甚至怀疑这样简洁的语句是如何实现问题求解的。 只有深刻理解了递归函数的运行过程,才能真正理解递归技术,从而设计递归程序。 采用图示方法描述递归函数的执行过程,从中可较直观地了解到递归函数的执行情况,具体方法如下: (1)顺序写出函数执行的各语句,并用有向弧表示语句的执行次序; (2)对函数的每个递归调用,写出对应的函数调用,从调用处画一条有向弧指向被调用函数入口,表示调用路线,从被调用函数末尾处画一条有向弧指向调用语句的下面,表示返回路线; (3)在返回路线上标出本次调用所得的函数值。 例1Fibonacci序列(Fibonaccisequence)。 把一对兔子(雌、雄各一只)放到围栏中,每个月这对兔子都生出一对新兔子,其中雌、雄各一只,从第二个月开始。 每对新兔子每个月也生出一对新兔子,也是雌、雄各一只,一年后围栏中有多少对兔子? 令f(n)表示第n个月开始时围栏中的兔子对数,显然有f (1)=1,f (2)=1,在第n个月的开始,那些第n-1个月初在围栏中的兔子仍然存在,而每对在第n-2个月就已经在围栏中的兔子会生均出一对新兔子,所以满足以下递推关系式: 求解Fibonacci序列的递归算法用C++语言描述如下: intFib(intn) { if(n==1||n==2)return1; elsereturnFib(n-1)+Fib(n-2); } 当n=5时Fibonacci序列的递归算法的执行轨迹如图4.17所示,实线表示深一层递归,虚线表示调用返回,虚线上的数字表示返回值,有向弧上的数字序号表示递归调用和返回的执行顺序。 例2汉诺塔问题(TowerofHanoi)。 在塔A上有n个金碟,所有碟子按从大到小的次序从塔底堆放至塔顶,紧挨着这座塔有另外两座塔(塔B和塔C),请将塔A上的碟子移动到塔C上去,其间可以借助于塔B的帮助。 每次只能移动一个碟子,任何时候都不能把一个碟子放在比它小的碟子上面。 汉诺塔问题的求解是一个典型的递归求解过程,具体算法如下: voidHanoi(intn,charA,charB,charC) { if(n==1)cout<"< else{ Hanoi(n-1,A,C,B);//将n-1个碟子从A借助C移到B上
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 阅读 材料 遗传 算法
![提示](https://static.bdocx.com/images/bang_tan.gif)