《算法基础:打开算法之门》一1.2 资源利用

本节书摘来自华章出版社《算法基础:打开算法之门》一书中的第1章,第1.2节,作者 [美]托马斯 H 科尔曼(Thomas H Cormen),更多章节内容可以访问云栖社区“华章计算机”公众号查看

1.2 资源利用

什么样的算法才能称为高效使用计算资源的算法呢?我们在讨论近似算法时提及了一个衡量效率的标准:时间。一个能给出正确输出但是会花费很长时间才能得出结果的算法可能是没有价值的。如果你的GPS需要一个小时才能计算出推荐的驾驶路线,你还会愿意打开GPS吗?诚然,一旦我们知道某算法能给出一个正确输出,时间便是我们用来衡量算法效率的主要方式。但是时间不是唯一的衡量标准。由于一个计算机算法必须能够在可用的内存空间上运行,因此我们可能还需要考虑该算法需要占用多大的计算机内存空间(它的“内存占用量”)。算法可能需要占用的其他资源还包括:网络通信、随机比特(由于随机算法需要产生随机数的资源)和磁盘操作(针对需要处理存储在磁盘上的数据的算法)。

类似大多数算法书,本书中我们将着重研究一个资源——时间。我们如何判定算法所需的时间呢?与正确性不同,正确性与运行该算法的特定计算机无关,而算法的实际运行时间还与算法本身之外的几个因素有关:计算机的速度、实现算法的编程语言、将源程序转换成计算机能执行的目标代码的编译器或者解释器、程序员的程序编写技术,以及与正运行的程序并行执行的其他进程。现假定算法运行在一个数据均存储在内存中的计算机上。

为了衡量一个算法的速度,如果我们通过在特定计算机上编写一个具体的程序,并用一个给定的输入来测试算法所需要的时间,则我们不会了解对于不同大小的输入,甚至对同样大小的不同输入,算法的运行速度会有多快。如果我们还要比较针对同一问题的两个不同算法的相对运行速度,4则我们必须实现这两种算法,并在各种不同规模的输入下对它们进行对比测试。因此,我们应该如何来评估一个算法的速度呢?

上述问题的答案需要综合以下两点。首先,我们要确定算法的输入规模。例如在路径寻找的例子中,输入可能是路线图中的某种表示,输入的规模依赖于交叉点的数目和连接交叉点的道路数目。(由于我们将所有的距离均以数字表示,数字对于计算机输入占用同样大小的空间,因此道路的实际尺寸和实际长度对输入规模均没有影响。)举一个更简单的例子,搜索某一个特定项是否出现在一个给定列表中,此问题的输入规模是列表中项的数目。

其次,我们考虑随着输入规模的增加,表示算法运行时间的函数会如何增长——运行时间的增长速率。在第2章中,我们将看到用来描述算法运行时间的符号,但最有趣的是,我们仅仅关注影响算法运行时间的主项,而不关心系数。也就是说,我们关注运行时间的增长量级。例如,假设我们能确定搜索一个具有n项的表的算法需要花费50n+125个机器周期。其中,当n≥3时,50n相对于125对算法有更大的影响。且随着n变得更大,50n相对于125对算法的影响就更加明显。因此,当我们描述这个算法的运行时间时,我们不用考虑低阶项125。可能令你更惊讶的还有我们舍弃了系数50,因此我们将运行时间表示为相对于输入规模n的线性函数。再举一例,如果一个算法需要20n3+100n2+300n+200个机器周期,我们将称该算法的运行时间随着n3数量级增长。同理,低阶项——100n2、300n和200——随着输入规模n的增加,变得越来越不显著。

实际上,我们忽视的系数的确会有影响。但算法本身如此依赖外在因素以至于完全可能出现这样的情况:如果我们要比较算法A和算法B的运行时间,且它们有相同的增长量级,并且具有相同的输入,那么在机器、编程语言、编译器/解释器和程序员的某一特定组合下,A的运行速度可能快于B,而在另一个组合下时,B的运行速度可能快于A。当然,如果算法A和B都能产生正确的输出,且A的运行速度始终是B的两倍,那么在相同的条件下,5我们总会更倾向于选择算法A而不是算法B。然而,从抽象角度比较算法时,我们只关注算法的增长顺序,而会忽视主项的系数或者低阶项。本章中我们要问的最后一个问题是:“为什么我要关注计算机算法?”该问题的答案取决于你是什么样的人。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你想知道你的GPS是如何在几秒钟内从看起来无数多条可能路径中找到到达目的地的最快捷路径的吗?当你在网上购物时,你的信用卡账号是如何被保护的呢?答案均是算法。本书是关于计算机算法基础的权威指南。在本书中,作者展示了计算机如何通过算法解决问题。 读者将学习到什么是计算机算法,如何描述计算机算法,以及如何评估计算机算法。读者还将学习到在计算机中查找信息的简单方法;在计算机中将信息按照某个预定的顺序重排(“排序”);如何解决那些在计算机中能使用一种被称为“图”的数学结构来建模的基本问题(可用于对道路网建模,针对任务间的依赖建模,以及金融套利交易建模);如何解决关于字符串(例如DNA结构)的问题;密码学的基本原理;数据压缩的基本原理;甚至那些至今还没有人得出如何借助计算机在一段合理的时间内求解的问题。 计算机是如何解决问题的呢?小小的GPS是如何只在几秒钟内就从无数条可能路径中找出到达目的地的最快捷路径的呢?在网上购物时,又如何防止他人窃取你的信用卡账号呢?解决这些问题,以及大量其他问题的答案均是算法。我写本书的目的就是为你打开算法之门,解开算法之谜。 我是《算法导论》的合著者之一。《算法导论》是一本特别好的书(当然,这是我个人的主观评价),但是它确实相当专业。 本书并不是《算法导论》,甚至不能被称为一本教材。它既没有对计算机算法领域进行广度或深度的研究,也没有遵照惯例来讲述设计计算机算法的方法,甚至连一道需要读者自己求解的难题或者练习题也没有。 那么,这是一本什么样的书呢?如果你符合如下条件,那么就可以开始阅读之旅了: ●你对计算机如何解决问题感兴趣; ●你想知道如何评估这些解决方案的质量; ●你想了解计算方面的问题和这些问题的解决方案是如何与非计算机世界关联起来的; ●你能处理一点数学运算; ●你不需要编写过计算机程序(当然,编写过程序更好)。 一些计算机算法方面的书籍是讲述理论概念的,并涉及非常少的技术细节;一些书籍关注的全是技术细节;而另外一些书籍是介于这两者之间的。每类图书都有自己的定位,我将本书定位于介于两者之间。诚然,本书涉及了一些数学知识,并且部分地方阐述得非常仔细,但是我已经竭力避免深入阐述细节(或许除了本书的末尾部分,我无法克制住自己,阐述了一些细节知识)。 我认为本书有点像开胃菜。设想你去了一家意大利餐厅,点了一份开胃菜,直到吃完开胃菜,你才会决定是否点其余食物。开胃菜到了,你就开始用餐了。或许你不喜欢吃开胃菜,并且决定不点其他菜了。可能你喜欢吃开胃菜,但是吃完它,你就感觉饱了,因此不需要点其他菜了。或者也有可能你喜欢吃开胃菜,但你并没有吃饱,此时你便开始期待其他菜了。将本书看作开胃菜,我希望能够产生后两种结果之一:或者读完了本书,你就很满足,感觉没有必要再深入探究算法世界了;或者你非常喜欢从本书中所学到的知识,以至于你想要学习更多算法方面的内容。每一章最后一节的标题为“拓展阅读”,其中会介绍更多关于该章主题的更为深入的书籍和文章。 你将从本书中学到什么: 我无法断定你将从本书中学到什么。如下是我希望你能从本书中学到的: ●什么是计算机算法,能够采用一种方式来描述计算机算法,以及如何评估算法。 ●在计算机中查找信息的简单方式。 ●在计算机中重排信息以使其以一种预定顺序排列的方法。(我们称这一任务为“排序”。) ●如何解决那些能在计算机中以一种称为“图”的数学结构建模的基本难题。在许多应用中,利用图建模的领域包括:道路网(哪些十字路口到哪些十字路口有直接相连的道路,这些道路有多长),任务间的依赖关系(哪个任务必须在其他任务之前完成),金融关系(世界各国货币间的汇率是多少),或者是人与人之间的联系(谁认识谁?谁讨厌谁?哪个演员和哪个演员出现在同一个电影中等)。 ●如何解决关于文本字符串的问题。其中一些问题在某些领域有所应用,例如生物学领域,其中字符表示基本的分子,字符串表示DNA结构。 ●密码学背后的基本原理。即使你自己从来没有加密过一条信息,你的计算机很可能已经对它执行加密操作了(例如当你在网上购物时)。 ●数据压缩的基本概念,这远远超过了“f u cn rd ths u cn gt a gd jb n gd pay”背后的压缩原理。 ●计算机在任意合理的时间内都难以解决的一些问题,或者至少还没有人想出如何解决的问题。 为了理解本书中的内容,你需要事先了解什么 正如我之前所说的,本书中涉及部分数学知识。如果你害怕数学,那么你可以尝试着跳过它,或者你也可以尝试着阅读涉及更少专业技术知识的书籍。但是我已经尽力做到令数学部分变得容易理解了。 我假定你从来没有写过,甚至从来没有读过一个计算机程序。如果你能看懂提纲的内容,就应该能够理解我是如何表达每一步算法,以及如何将这些步骤合并在一起组合成一个完整的算法的。如果你听到过
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值