通常,要分析的最重要的资源就是运行时间。有几个因素影响着程序的运行时间。有些因素(如使用编译器和计算机)显然超出了任何理论模型的范畴,因此,虽然它们是重要的,但是我们在这里还是不能考虑它们。剩下的主要因素是所使用的算法以及对该算法的输入。

典型的情形是,输入的大小是主要的考虑方面。我们定义两个函数Tavg(N)和Tworst(N),分别为算法对于输入量N所花费的平均运行时间和最坏情况的运行时间。显然,Tavg(N)<=Tworst(N)。

如果存在多于一个的输入,那么这些函数可用有多于一个的变量。

偶尔也分析一个算法的最好情形的性能。不过,通常这没有什么重要意义,因为它不代表典型的行为。平均情形性能常常反映典型的行为,而最坏的性能则代表对任何可能输入的性能一种保证。还要注意,虽然在这一章我们分析的是Java程序,但所得到的界实际上是算法的界而不是程序的界。程序是算法以一种特殊编程语言的实现,程序设计语言的细节几乎总是不影响大于O的答案。如果一个程序比算法分析提出的速度慢得多,那么可能存在低效率的实现。这在类似C++的语言中很普遍,比如,数组可能当作整体而被漫不经心的拷贝,而不是由引用来传递。不管怎么说,这在Java中也可能出现。

一般来说,如果没有相反的指定,则所需要的量是最坏情况的运行时间。其原因之一是它对所有的输入提供了一个界限,包括特别坏的输入,而平均情况分析不提供这样的界。另一个原因是平均情况的界计算起来通常要困难得多。在某些情况下,“平均”的定义可能影响分析的结果。(例如,什么是下属问题的平均输入?)

作为一个例子,我们将在下一节考虑下述问题:

最大子序列和问题:

例如:对于输入-2,11,-4,13,-5,-2,答案为20(从A2到A4) 。

这个问题之所以有吸引力,主要是因为存在求解它的很多算法,而这些算法的性能又差异很大。我们将讨论求解该问题的四种算法。这四种算法在某台计算机上(究竟是哪一台具体的计算机并不重要)的运行时间。如图:

在表中有几个重要的情况值得注意。对于小量的输入,这些算法都在眨眼之间完成,因此如果只是小量输入的情形,那么花费大量的努力去设计聪明的算法恐怕就太不值得了。

另一方面,近来对于重写那些不再合理的基于小输入量假设而在五年以前编写的程序确实存在巨大的市场。现在看来,这些程序太慢了,因为它们用的是一些低劣的算法。对于大量的输入,算法4显然是最好的选择(虽然算法3也可以用)。

其次,表中所给的时间不包括读入数据所需要的时间。对于算法4,仅仅从磁盘读入数据所用的时间很可能在数量级上比求解上述问题所需要的时间还要大。这是许多有效算法的典型特点。数据的读入一般是个瓶颈;一旦数据读入,问题就会迅速解决。但是,对于低效率的算法情况就不同了,它必然要占用大量的计算机资源。因此只要可能,使得算法足够有效而不至成为问题的瓶颈是非常重要的。

注意到具有线性复杂度的算法4表现很好,当问题的规模增长了十倍的时候,其运行的时间也增长十倍。而具有平方复杂度的算法2就不行了,十倍的规模增长导致运行时间大于有百倍(10的2次方)的增长。而立方级复杂度的算法1的运行时间则由千倍(10的3次方)的增长。对于N=100000,我们可以预期算法1将花费近乎90000秒或一天的时间。类似地,我们可预期算法2用大约333秒来完成N=1000000。然而,算法2也可能花费更多的时间,因为在现代计算机中,内存存取N=1000000可能比处理N=100000要慢,这取决于内存缓存的大小。

再看图:

左图指出了四种算法运行时间的增长率。尽管该图只包含N从10到100的值,但是相对增长率还是很明显的。虽然O(NlogN)算法的图看起来是线性的,但是用直尺的边(或是一张纸)容易验证它并不是直线。虽然O(N)算法的图看似直线,但这只是因为对于小的N值其中的常数项大于线性项。右图中更显示对于更大值的性能。该图明显地表明,对于即使是适度大小的输入量低效算法依然是多么的无用。

<数据结构与算法分析>读书笔记--要分析的问题的更多相关文章

  1. <数据结构与算法分析>读书笔记--最大子序列和问题的求解

    现在我们将要叙述四个算法来求解早先提出的最大子序列和问题. 第一个算法,它只是穷举式地尝试所有的可能.for循环中的循环变量反映了Java中数组从0开始而不是从1开始这样一个事实.还有,本算法并不计算 ...

  2. <数据结构与算法分析>读书笔记--运行时间计算

    有几种方法估计一个程序的运行时间.前面的表是凭经验得到的(可以参考:<数据结构与算法分析>读书笔记--要分析的问题) 如果认为两个程序花费大致相同的时间,要确定哪个程序更快的最好方法很可能 ...

  3. <数据结构与算法分析>读书笔记--函数对象

    关于函数对象,百度百科对它是这样定义的: 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象.又称仿函数. 听起来确实很难懂,通过搜索我找到一篇 ...

  4. <数据结构与算法分析>读书笔记--利用Java5泛型实现泛型构件

    一.简单的泛型类和接口 当指定一个泛型类时,类的声明则包括一个或多个类型参数,这些参数被放入在类名后面的一对尖括号内. 示例一: package cn.generic.example; public ...

  5. <数据结构与算法分析>读书笔记--数学知识复习

    数学知识复习是<数据结构与算法分析>的第一章引论的第二小节,之所以放在后面,是因为我对数学确实有些恐惧感.不过再怎么恐惧也是要面对的. 一.指数 基本公式: 二.对数 在计算机科学中除非有 ...

  6. <数据结构与算法分析>读书笔记--运行时间中的对数及其分析结果的准确性

    分析算法最混乱的方面大概集中在对数上面.我们已经看到,某些分治算法将以O(N log N)时间运行.此外,对数最常出现的规律可概括为下列一般法则: 如果一个算法用常数时间(O(1))将问题的大小削减为 ...

  7. <数据结构与算法分析>读书笔记--模型

    为了在正式的构架中分析算法,我们需要一个计算模型.我们的模型基本上是一台标准的计算机,在机器中指令被顺序地执行.该模型有一个标准的简单指令系统,如加法.乘法.比较和赋值等.但不同于实际计算机情况的是, ...

  8. <数据结构与算法分析>读书笔记--实现泛型构件pre-Java5

    面向对象的一个重要目标是对代码重用的支持.支持这个目标的一个重要的机制就是泛型机制:如果除去对象的基本类型外,实现的方法是相同的,那么我们就可以用泛型实现来描述这种基本的功能. 1.使用Object表 ...

  9. <数据结构与算法分析>读书笔记--递归

    一.什么是递归 程序调用自身的编程技巧称为递归( recursion).递归做为一种算法在程序设计语言中广泛应用. 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的 ...

随机推荐

  1. Asp.Net MVC3 简单入门详解过滤器Filter(转载)

    前言 在开发大项目的时候总会有相关的AOP面向切面编程的组件,而MVC(特指:Asp.Net MVC,以下皆同)项目中不想让MVC开发人员去关心和写类似身份验证,日志,异常,行为截取等这部分重复的代码 ...

  2. 转载 基于JAVA每月运势api调用代码实例

    代码描述:基于JAVA每月运势api调用代码实例 接口地址:http://www.juhe.cn/docs/api/id/58 原文链接:http://outofmemory.cn/code-snip ...

  3. CentOS6.5安装mysql以及常见问题的解决

    前言 最近在学习Linux系统,今天在安装MySQL数据库时出现很多问题,花费了两个小时终于解决,故记录下来以供大家参考.(本人目前还在学习阶段,下面写到的是自己结合网上查到的资料以及各位前辈给出的解 ...

  4. 组件化和 React

    一,对组件化的理解 1,组件的封装 -视图 -数据 -变化逻辑(数据驱动视图变化) 例: import React, { Component } from 'react'; import List f ...

  5. loadrunner 场景设计-制定负载测试计划

    by:授客 QQ:1033553122 场景设计-制定负载测试计划 步骤1.分析应用程序 你应该对硬件和软件组建,系统配置和典型的使用场景很熟悉.这些应用程序的分析保证你在使用loadrunner进行 ...

  6. Python中识别DataFrame中的nan

    # 识别python中DataFrame中的nanfor i in pfsj.index: if type(pfsj.loc[i]['WZML']) == float: print('float va ...

  7. Chrome及Chrome内核浏览器改变开发者工具字体大小

    1.打开浏览器,按F12调用开发者工具 2.按Ctrl+数字加号键,可看到字体变大,按Ctrl+数字减号键,字体变小 3.重新启动浏览器后字体仍然保持修改后的字体大小

  8. AD域自定义属性《完整》

    1.安装Active Directory 架构,下载:adminpak.msi安装. 2.以管理员运行cmd,执行:regsvr32 schmmgmt.dll(该命令将在计算机上注册“schmmgmt ...

  9. mysqld_safe启动服务器总结

    mysqld_safe是服务端工具,用于启动mysqld,并且是mysqld的守护进程,mysqld_safe加&在后台运行$BASEDIR/bin/mysqld_safe & 优点就 ...

  10. linux内网IP如果判断出网IP地址

    [root@jumpserver ~]# curl https://ip.cn当前 IP: 162.14.210.16 来自: 河南省郑州市 xx网络