28 | 数据流分析:你写的程序,它更懂

上一讲,提到了删除公共子表达式、拷贝传播等本地优化能做的工作,其实,这几个工作也可以在全局优化中进行。

只不过,全局优化中的算法,不会像在本地优化中一样,只针对一个基本块。而是更复杂一些,因为要覆盖多个基本块。这些基本块构成了一个 CFG,代码在运行时有多种可能的执行路径,这会造成多路径下,值的计算问题,比如活跃变量集合的计算。

当然了,还有些优化只能在全局优化中做,在本地优化中做不了,比如:

代码移动(code motion)能够将代码从一个基本块挪到另一个基本块,比如从循环内部挪到循环外部,来减少不必要的计算。

部分冗余删除(Partial Redundancy Elimination),它能把一个基本块都删掉。

总之,全局优化比本地优化能做的工作更多,分析算法也更复杂,因为 CFG 中可能存在多条执行路径。不过,我们可以在上一节课提到的本地优化的算法思路上,解决掉多路径情况下,V 值的计算问题。而这种基于 CFG 做优化分析的方法框架,就叫做数据流分析。

本节会把全局优化的算法思路讲解清楚,借此引入数据流分析的完整框架。而且在解决多路径情况下,V 值的计算问题时,我还会带你学习一个数学工具:半格理论。这样,你会对基于数据流分析的代码优化思路建立清晰的认识,从而有能力根据需要编写自己的优化算法。

数据流分析的场景:活跃性分析

上一讲,已经讲了本地优化时的活跃性分析,那时,情况比较简单,你不需要考虑多路径问题。而在做全局优化时,情况就要复杂一些:代码不是在一个基本块里简单地顺序执行,而可能经过控制流图(CFG)中的多条路径。我们来看一个例子(例子由 if 语句形成了两条分支语句):

基于这个 CFG,我们可以做全局的活跃性分析,从最底下的基本块开始,倒着向前计算活跃变量的集合(也就是从基本块 5 倒着向基本块 1 计算)。

这里需要注意,对基本块 1 进行计算的时候,它的输入是基本块 2 的输出,也就是{a, b, c},和基本块 3 的输出,也就是{a, c},计算结果是这两个集合的并集{a, b, c}。也就是说,基本块 1 的后序基本块,有可能用到这三个变量。这里就是与本地优化不同的地方,我们要基于多条路径来计算。

基于这个分析图,我们马上发现 y 变量可以被删掉(因为它前面的活变量集合{x}不包括 y,也就是不被后面的代码所使用),并且影响到了活跃变量的集合。

删掉 y 变量以后,再继续优化一轮,会发现 d 也可以删掉。

d 删掉以后,2 号基本块里面已经没有代码了,也可以被删掉,最后的 CFG 是下面这样:

到目前为止,我们发现:全局优化总体来说跟本地优化很相似,唯一的不同,就是要基于多个分支计算集合的内容(也就是 V 值)。在进入基本块 1 时,2 和 3 两个分支相遇(meet),我们取了 2 和 3V 值的并集。这就是数据流分析的基本特征,你可以记住这个例子,建立直观印象。

但是,上面这个 CFG 还是比较简单的,因为它没有循环,属于有向无环图。这种图的特点是:针对图中的每一个节点,我们总能找到它的前序节点和后序节点,所以我们只需要按照顺序计算就好了。但是如果加上了环路,就不那么简单了,来看一看下面这张图:

基本块 4 有两个后序节点,分别是 5 和 1,所以要计算 4 的活跃变量,就需要知道 5 和 1 的输出是什么。5 的输出好说,但 1 的呢?还没计算出来呢。因为要计算 1,就要依赖 2 和 3,从而间接地又依赖了 4。这样一来,1 和 4 是循环依赖的。再进一步探究的话,你发现其实 1、2、3、4 四个节点之间,都是循环依赖的。

所以说,一旦在 CFG 中引入循环回路,严格的前后计算顺序就不存在了。那你要怎么办呢?

其实,我们不是第一次面对这个处境了。在前端部分,我们计算 First 和 Follow 集合的时候,就会遇到循环依赖的情况,只不过那时候没有像这样展开,细细地分析。不过,你可以回顾一下17 讲和18 讲,那个时候你是用什么算法来破解僵局的呢?是不动点法。在这里,我们还是要运用不动点法,具体操作是:给每个基本块的 V 值都分配初始值,也就是空集合。

然后对所有节点进行多次计算,直到所有集合都稳定为止。第一遍的时候,我们按照 5-4-3-2-1 的顺序计算(实际上,采取任何顺序都可以),计算结果如下:

如果现在计算就结束,我们实际上可以把基本块 2 中的 d 变量删掉。但如果我们再按照 5-4-3-2-1 的顺序计算一遍,就会往集合里增加一些新的元素(在图中标的是橙色)。这是因为,在计算基本块 4 的时候,基本块 1 的输出{b, c, d}也会变成 4 的输入。这时,我们发现,进入基本块 2 时,活变量集合里是含有 d 的,所以 d 是不能删除的。

你再仔细看看,这个 d 是哪里需要的呢?是基本块 3 需要的:它会跟 1 去要,1 会跟 4 要,4 跟 2 要。所以,再次证明,1、2、3、4 四个节点是互相依赖的。

我们再来看一下,对于活变量集合的计算,当两个分支相遇的情况下,最终的结果我们取了两个分支的并集。

在上一讲,我们说一个本地优化分析包含四个元素:方向(D)、值(V)、转换函数(F)和初始值(I)。在做全局优化的时候,我们需要再多加一个元素,就是两个分支相遇的时候,要做一个运算,计算他们相交的值,这个运算我们可以用大写的希腊字母Λ(lambda)表示。包含了 D、V、F、I 和Λ的分析框架,就叫做数据流分析

那么Λ怎么计算呢?研究者们用了一个数学工具,叫做“半格”(Semilattice),帮助做Λ运算。

直观地理解半格理论

如果要从数学理论角度完全把“半格”这个概念说清楚,需要依次介绍清楚“格”(Lattice)、“半格”(Semilattice)和“偏序集”(Partially Ordered Set)等概念。我想这个可以作为爱好数学的同学的一个研究题目,或者去向离散数学的老师求教。在我们的课程里,只是通过举例子,让你对它有直观的认识。

首先,半格是一种偏序集。偏序集就是集合中只有部分成员能够互相比较大小。举例来说会比较直观。在做全局活跃性分析的时候,{a, b, c}和{a, c}相遇,产生的新值是{a, b, c}。我们形式化地写成{a, b, c} Λ {a, c} = {a, b, c}。

这时候我们说{a, b, c}是可以跟{a, c}比较大小的。那么哪个大哪个小呢?

如果 XΛY=X,我们说 X<=Y。

所以,{a, b, c}是比较小的,{a, c}是比较大的。

当然,{a, b, c}也可以跟{a, b}比较大小,但它没有办法跟{c, d}比较大小。所以把包含了{{a, b, c}、{a, c}、{a, b}、{c, d}…}这样的一个集合,叫做偏序集,它们中只有部分成员之间可以比较大小。哪些成员可以比较呢?就是下面的半格图中,可以通过有方向的线连起来的。

半格可以画成图形,理解起来更直观,假设我们的程序只有 a, b, c 三个变量,那么这个半格画成图形是这样的:

沿着上面图中的线,两个值是可以比较大小的,按箭头的方向依次减少:{}>{a}>{a, b}> {a, b, c}。如果两个值之间没有一条路径,那么它们之间就是不能比较大小的,就像{a}和{b}就不能比较大小。

对于这个半格,我们把{}(空集)叫做 Top,Top 大于所有的其他的值。而{a, b, c}叫做 Bottom,它是最小的值。

在做活跃性分析时,我们的Λ运算是计算两个值的最大下界(Greatest Lower Bound)。怎么讲呢?就是比两个原始值都小的值中,取最大的那个。{a}和{b}的最大下界是{a, b},{a, b, c} 和{a, c}的最大下界就是{a, b, c} 。

如果一个偏序集中,任意两个元素都有最大下界,那么这个偏序集就叫做交半格(Meet Semilattice)

与此相对应的,如果集合中的每个元素都有最小上界(Least Upper Bound),那么这个偏序集叫做并半格(Join Semilattice)

如果一个偏序集既是交半格,又是并半格,我们说这个偏序集是一个格,示例的这个偏序集就是一个格。

你可能会奇怪,为什么要引入这么复杂的一套数学工具呢?不就是集合运算吗?两个分支相遇,就计算它们的并集,不就可以了吗?事情没那么简单。因为并不是所有的分析,其 V 值都是一个集合,就算是集合,相交时的运算也不一定是求并集,而有可能是求交集。

我们通过另一个案例来分析一下非集合的半格运算:常数传播

数据流分析的场景:常数传播

常数传播,就是如果知道某个变量的值是个常数,那么就把用到这个变量的表达式,都用常数去替换。看看下面的例子,在基本块 4 中,a 的值能否用一个常数替代?

答案是不能。到达基本块 4 的两条路径,一条 a=3,另一条 a=4。我们不知道在实际运行的时候,会从哪条路径过来,所以这个时候 a 的取值是不确定的,基本块 4 中的 a 无法用常数替换。

那么,运用数据流分析的框架怎么来做常数传播分析呢?

在这种情况下,V 不再是一个集合,而是 a 可能取的常数值,但 a 有可能不是一个常数啊,所以我们再定义一个特殊的值:Top(T)。

除了 T 之外,我们再引入一个与 T 对应的特殊值:Bottom(它的含义是,某个语句永远不会被执行)。总结起来,常数传播时,V 的取值可能是 3 个:

常数 c

Top:意思是 a 的值不是一个常数

Bottom:某个语句不会被执行。

这些值是怎么排序的呢?最大的是 Top,中间各个常数之间是无法比较的,Bottom 是最小的。

接下来,我们看看如何计算多个 V 值相交的值。

我们再把计算过程形式化一下。在这个分析中,当我们经过每个语句的时候,V 值都可能发生变化,我们用下面两个函数来代表不同地方的 V 值:

C(a, s, in)。表示在语句 s 之前 a 的取值,比如,C(a, b:=a+2, in) = 3。

C(a, s, out)。表示在语句 s 之后 a 的取值,比如,C(a, a:=4, out) = 4。

如果 s 的前序有 i 条可能的路径,那么多个输出和一个输入“C(a, si, out) 和 C(a, s, in)”的关系,可以制定一系列规则:

1. 如果有一条输入路径是 Top,或者说 C(a, si, out) 是 Top,那么结果 C(a, s, in) 就是 Top。

2. 如果输入中有两个不同的常数,比如 3 和 4,那么结果也是 Top(我们的示例就是这种情况)。

3. 如果所有的输入都是相同的常数或 Bottom,那么结果就是该常数。如果所有路径 a 的值都是 3,那么这里就可以安全地认为 a 的值是 3。那些 Bottom 路径不影响,因为整条路径不会执行。

4. 如果所有的输入都是 Bottom,那么结果也是 Bottom。

上面的这 4 个规则,就是一套半格的计算规则。

在这里,我们也可以总结一下它的转换规则,也就是 F,考虑一下某个 Statement 的 in 值和 out 值的关系,也就是经过该 Statement 以后,V 值会有啥变化:

1. 如果输入是 Bottom,那么输出也是 Bottom。也就是这条路径不会经过。

2. 如果该 Statement 就是“ a := 常数”,那么输出就是该常数。

3. 如果该 Statement 是 a 赋予的一个比较复杂的表达式,而不是常数,那么输出就是 Top。

4. 如果该 Statement 不是对 a 赋值的,那么 V 值保持不变。

好了,转换函数 F 也搞清楚了。初始值 I 是什么呢?是 Top,因为一开始的时候,a 还没有赋值,所以不会是常数;方向 D 是什么呢?D 是向下。这个时候,D、V、F、I 和Λ5 个元素都清楚了,我们就可以写算法实现了。

课程小结

本节,我们基于全局优化分析的任务,介绍了数据流分析这个框架,并且介绍了半格这个数学工具。希望你在本讲记住几个要点

全局分析比本地分析多处理的部分就是 CFG,因为有了多条执行分支,所以要计算分支相遇时的值,当 CFG 存在环路的时候,要用不动点法来计算出所有的 V 值。

数据流分析框架包含方向(D)、值(V)、转换函数(F)、初始值(I)和交运算(Λ)5 个元素,只要分析清楚这 5 个元素,就可以按照固定的套路来编写分析程序。

对于半格理论,关键是要知道如何比较偏序集中元素的大小,理解了这个核心概念,那么求最大下界、最小上界这些也就没有问题了。

数据流分析也是一个容易让学习者撞墙的知识点,特别是再加上“半格”这样的数学术语的时候。不过,我们通过全局活跃性分析和全局常数传播的示例,对“半格”的抽象数学概念建立了直觉的理解。遇到全局分析的任务,你也应该能够比照这两个示例,设计出完整的数据流分析的算法了。不过建议你,还是要按照上一讲中对 LLVM 优化功能的介绍,多做几个例子实验一下。

一课一思

如果我们想做一个全局分析,用于删除公共子表达式,它的数据流分析框架应该是怎样的?也就是 D、V、F、I 和Λ各自应该如何设计呢?



数据流分析是一种用于全局优化的算法框架,能够解决多路径下的值计算问题。在全局优化中,算法需要覆盖多个基本块,构成控制流图(CFG),并考虑多种可能的执行路径。数据流分析的场景之一是活跃性分析,它在全局优化中变得更加复杂,因为代码可能经过多条路径执行。通过倒着向前计算活跃变量的集合,数据流分析可以发现可以被删除的变量,从而进行优化。当CFG中存在循环时,需要运用不动点法来计算每个基本块的活跃变量集合。数据流分析的分析框架包含了方向、值、转换函数、初始值和Λ运算,这使得它能够更好地处理全局优化中的复杂情况。此外,半格理论是数据流分析中的重要数学工具,用于比较偏序集中元素的大小,求最大下界和最小上界。

文章还介绍了半格理论的概念和应用,以及数据流分析在常数传播场景中的应用。常数传播是一种优化技术,通过替换变量的值为常数来提高程序性能。在常数传播中,V的取值可能是常数、Top(表示变量的值不是一个常数)和Bottom(表示某个语句不会被执行),并且需要根据特定规则进行计算。文章还提到了数据流分析框架的设计要点,以及对全局分析任务的思考和建议。

总的来说,本文通过介绍数据流分析和半格理论,以及在常数传播场景中的应用,帮助读者理解了全局优化中的复杂情况下如何进行值计算和优化,为读者提供了深入的技术知识和应用思路。 

  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
驰骋工作流引擎源码 产品名称: 驰骋.net工作流程引擎. 运行环境: BS结构. windows xp, windows server. win7 IIS6.0以上. .net4.0. Office2007 (如果需要单据打印.) 开发语言: VS2010, .net4.0 c#.net. 客户端: FireFox 3.0以上. IE7+,或者使用IE内核的浏览器. 组成部分: 流程图形设计器(有:cs版本与bs版本)/流程前台运行程序(BS结构)/流程服务(CS)/web的方式的表单设计器/BRP工具 基本功能: 图形化流程设计/智能表单web定义免程序开发/级联下拉框/流程轨迹/单据自定义打印/邮件短信工作到达通知/自动任务分配/支持sdk模式开发/简洁集成/消息侦听/丰富事件接口/报表定义/工作量分析/绩效考核/手机访问/支持sqlserve,oracle,mysql,access数据库 CCFlow功能: 管理就会开发基本流程,为单位流程管理系统,会SQL就能达到中级开发水平解决复杂的逻辑问题与其它系统耦合,有程基础就可以使用sdk做高级的开发. 程序运行组件清单. ***************************************************************** 1. .net 4.0 2, owc11.exe 用于生成数据图形分析。 3, SaveAsPDFandXPS.exe 生成pdf文件的组件.【选装】 4, iewebcontrols.msi 控件. 5, vs2010 开发环境(不进行二次开发不必要安装) ***************************************************************** ccflow 开源程序文件清单: ***************************************************************** 组件目录 D:\ccflow\Components 组件目录. D:\ccflow\Components\BP.En30 -- 底层基类. D:\ccflow\Components\BP.Web.Controls30 --bs控件层. D:\ccflow\Components\BP.WFV4 --工作流程引擎层 D:\ccflow\Components\BP.Win32.Controls --cs控件层. D:\ccflow\DLL -- 第三方组件中需要调用dll. D:\ccflow\Documents - 文档 D:\ccflow\VisualFlow --bs工作流程引擎前台. D:\ccflow\VisualWorkFlowServices - 流程服务程序. D:\ccflow\VisualFlowWebDesigner - silverlight流程设计器. D:\ccflow\CCFlowWord2007 - VSTO公文流程. D:\ccflow\ExpandingApplication 行业应用通用代码。 D:\ccflow\Tools 工具 关于: ccflow前台目录结构. D:\ccflow\VisualFlow\Comm --通用功能层. D:\ccflow\VisualFlow\Data -- 应用程序数据目录. 包含一些xml,等等。 D:\ccflow\VisualFlow\Data\Install 与安装有关系的文件 D:\ccflow\VisualFlow\Data\JSLib 系统javascript 函数库。 D:\ccflow\VisualFlow\Data\Language 语言包(完善中) D:\ccflow\VisualFlow\Data\Node cs流程设计器节点类型(cs流程设计器不在发展) D:\ccflow\VisualFlow\Data\XML xml配置文件不仅仅ccflow使用,bp框架也使用它。 用户数据目录。 D:\ccflow\VisualFlow\DataUser -- 用户数据目录。 D:\ccflow\VisualFlow\DataUser\Bill 单据打印生成数据. D:\ccflow\VisualFlow\DataUser\CyclostyleFile 单据模板数据 D:\ccflow\VisualFlow\DataUser\DtlTemplete 导入明细表模板文件. D:\ccflow\VisualFlow\DataUser\EmailTemplete 自定义邮件发送格式文件. D:\ccflow\VisualFlow\DataUser\JSLib 用户自定义函数库 D:\ccflow\VisualFlow\DataUser\JSLibData 用户自定义函数生成文件。 D:\ccflow\VisualFlow\DataUser\Log 系统日志文件 D:\ccflow\VisualFlow\DataUser\ReturnLog 退回日志文件. D:\ccflow\VisualFlow\DataUser\Siganture 签名文件. D:\ccflow\VisualFlow\DataUser\Style 用户自定义风格文件。 D:\ccflow\VisualFlow\DataUser\UploadFile 表单附件上传文件,单附件,与多附件。 D:\ccflow\VisualFlow\DataUser\XML 用户系统配置文件。 D:\ccflow\VisualFlow\WF\DocFlow -- 公文流程(目前还不是很完善) D:\ccflow\VisualFlow\OA -- 通用oa 组件(目前还不是很完善) D:\ccflow\VisualFlow\SDKFlowDemo -- sdk开发模式的案例. D:\ccflow\VisualFlow\WF\WAP -- 手机访问前台代码目录. (说明:对C级用户有效) D:\ccflow\VisualFlow\WF -- ccflow前台应用程序层(主要的功能都是在这个目录里面) D:\ccflow\VisualFlow\WF\Admin - 对ccflow的管理比如设计方向条件.报表定义... D:\ccflow\VisualFlow\WF\MapDef - 表单定义. D:\ccflow\VisualFlow\ClientBin - silverlight 程序.。 CCFlowDesigner.xap流程设计器,CCForm.xap表单设计器。 注意: 源码有详细使用文档,可以下载查看。 用户名是:51aspx 密码是 51aspx 管理员用户名是:admin 密码是 pub 默认添加的用户的密码均是pub 特此声明,网站版权归开发公司所有,此源码仅供学习交流之用,如有违者后果自负
一份优秀的数据分析报告产出流程 在每次的数据分析工作中,将分析过程与结果成一份通俗易的报告是工作的最后 一步,但是这对于一些人来说,也是最难的一步。 一份技术报告的目的是传递信息。然而,技术信息是很难让人理解的,因为它不仅复 杂,而且无法让人轻易的了解。将数学焦虑等融入到任何事情都可以被统计数据证实 这一流行观念中,你就可以明白为什么做数据分析报告是一份挑战。 一个人撰有效的数据分析报告的能力不应该被假定。它和为课堂作业一份只有指 导员才去看的课题报告不是一回事。 十分肯定的是,如果你还没有上过与撰数据分析报告相关的大学课程或者职业发展 课程,没有在工作中接受过相关的指导,并且也没有做过独立的相关性阅读,那么, 你需要学习一些关于撰技术报告的知识。 撰报告就像是任何其他的技能一样,要通过学习具体的流程和不断练习才能提升。 下面是四件你可以尝试用来提高你的技能的事情。 自主学习:了解其他人对技术作的认识。浏览与"统计分析报告"和"技术作"有关 的网站,这种网站有数以百万个。阅读相关书籍或指导手册,通过雅虎,谷歌或者 领英加入到相关的网络小组中去。将你自己沉浸在这个话题中,就像你在学校里做 过的那样。 了解批评:在你的职业生涯中,你将给出或者收到很多关于技术报告的批评。并不是 所有的批评都具有相同的价值。首先,你需要考虑是谁在批评?有的评论家从来没 有过数据分析报告,甚至有的从来没有分析过数据。但是,如果这个批评家是那 个付账单的人,那你还是想办法受着吧。如果是你给出批评的话,你需要学习如何 给出有建设性的批评。要尊重报告作者对作结构和形式的判断,除非这份报告 实在是太糟糕了。关注内容,做个友善的人。 下载案例:在网上寻找关于数据分析报告的例子(提示:搜索的时候加上"pdf"和" 下载"可能会有帮助)。评论这些例子。这些报告的受众是谁?传递的信息是什么 ?每份报告的优缺点有哪些?哪些报告你觉得属于好的例子?他们做的哪些工作是 你在将来工作时可能会想去做的? 找到适合你的:当你在网上查找与技术作相关的建议或者学习知识渊博的指导员开设 的课程时,你将会听到一些不同的观点。每个人都会提到受众和内容,但是大部分人 在报告结构、作风格及如何进行作方面的观点都很有局限性。如果专家让你做的 事情感觉不对的话,那就忽略它。只要确定你最终选择的方法适合你自己及将会读到 你的报告的受众就好了。 如果上面的四点你都做了,那么接下来就仅仅是练习的问题了。你会从你撰的每份 报告里学到一些东西。如果你对数据分析报告撰流程很陌生的话,那么可以考虑从 以下三方面进行学习。 01 明确内容 从你最了解的部分着手开始。在一份数据分析报告时,你最了解的部分应该是你分 析的统计数据、绘制的图形以及建立的模型。 你应该有能力去描述你是如何呈现总体特征的,如何生成这些数据的或者是提供了这 些数据的源头,在做探索性的分析时你发现了数据存在哪些问题,你是如何处理这些 数据的,对异常数据你做了怎样的处理,应用了怎样的变换方法,对于缺失的和重复 的数据你做了什么,你是如何处理违反假设的情况和不显著的结果的。 接下来,你需要决定什么是重要的内容,以及,哪些内容对报告阅读者来说是重要的 。因为除非你的报告是面向你的大学教授或者是同龄的数据分析专业人员,否则的 话,你可以十分确定的认为没有人想听你讲你是如何解决各类问题的,你用了什么技 巧,或者你在分析数据的时候多么努力。没有人在意你的结果是来自Excel表格还是 一段自己用R语言编程序。 一旦整理出了你需要的信息,就为这份报告一个概述,这样你就会知道你都要些 什么内容。这样做可以帮助你不偏离主线。你的总结或许可以选择以下三种形式中的 一种: 1.执行总结 执行总结面对的是决策者或者那些没有足够的时间或耐心去阅读超过400字的文章的 人。把你的概述缩减到一页以内,不要使用任何术语,只提供那些决策者需要的,可 以帮助他采取适当行动的结果信息(也就是:你想要传达的信息)。 2.总括 总括面对的是大部分读者,无论他们是否会阅读这份报告。一篇总括是报告内容的删 减版,并且关注点在你想要传达的信息上。总括的内容也不应超过几页纸。 3.摘要 摘要面对的是同专业的人以及其他可以看数据分析的人。一篇摘要的内容通常是一 页纸或者少于一页纸,并且总结了你所做的所有的重要的工作,从定义总体到评估效 应量。摘要通常被用在学术论文作中。一旦你知道了你的读者是谁,你就可以重新 撰概述以便抓住读者的注意力。 02 了解读者 每篇教你自学技术作的文章都会首先告诉读者要考虑他们撰报告的观众。即使如 此,或许很少有作者真的这样去做。 在统计分析中,你通常会先开始考虑你想要做出推断的那些总体所具有的特征。与之 相似的,当
在有关算法的书中,有一些叙述非常严谨,但不够全面;另一些涉及了大量的题材,但又缺乏严谨性。《算法导论(原书第3版)/计算机科学丛书》将严谨性和全面性融为一体,深入讨论各类算法,并着力使这些算法的设计和分析能为各个层次的读者接受。全书各章自成体系,可以作为独立的学习单元;算法以英语和伪代码的形式描述,具备初步程序设计经验的人就能看;说明和解释力求浅显易,不失深度和数学严谨性。   《算法导论(原书第3版)/计算机科学丛书》全书选材经典、内容丰富、结构合理、逻辑清晰,对本科生的数据结构课程和研究生的算法课程都是非常实用的教材,在IT专业人员的职业生涯中,《算法导论(原书第3版)/计算机科学丛书》也是一本案头必备的参考书或工程实践手册。   第3版的主要变化:   ·新增了van Emde Boas树和多线程算法,并且将矩阵基础移至附录。   ·修订了递归式(现在称为“分治策略”)那一章的内容,广泛地覆盖分治法。   ·移除两章很少讲授的内容:二项堆和排序网络。   ·修订了动态规划和贪心算法相关内容。   ·流网络相关材料现在基于边上的全部流。   ·由于关于矩阵基础和Strassen算法的材料移到了其他章,矩阵运算这一章的内容所占篇幅小。   ·修改了对Knuth-Morris-Pratt字符串匹配算法的讨论。   ·新增100道练习和28道思考题,还新并补充了参考文献。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值