最好最坏和平均情况下的性能分析

现在有一个问题,对于所有的输入来说,前面得到的结果是否都成立呢?第二种排序法在少量字符串的时候性能也许是最好的。但是,输入数据有很多地方可能变化:

输入数据可能有1 000 000个字符串。算法如何处理如此大规模的数据?

输入数据可能会是部分有序状态,也就是说,几乎所有的元素所在的位置离最终位置并不是很远。

输入数据可能包含重复的值。

无论输入数据的规模n是多少,输入数据都可以从一个小得多的数据集扩展而来,不过会有相当多的重复值。

虽然从图2-2上来看,第四种排序法在排序n个乱序字符串的时候是最慢的,但是处理已经排序的数据却是最快的。但是,随着n的增长,第四种排序法的领先优势消失得非常快,我们从图2-3上可以看到,在对16个乱序的字符串进行排序时,第四种排序法就已经失去领头羊的位置了。

 
 

尽管如此,假设一个包含n个字符串的输入,并且这个输入已经是几乎有序,其中n/4个字符串(占总字符串的25%)被交换到仅仅是离最终位置4个元素。最终结果如图2-4所示,我们看到第四种排序法性能表现远远好于其他的排序算法。

 

我们得到这样一个结论,对于许多问题来说,并不存在单一的最优算法。选择一个算法需要对问题有着充分的理解,并知道这个问题将要处理数据规模的概率分布情况,还有算法的实际行为也必须要考虑到。

在这里我们提供一些指导,算法通常会分成三种情况进行分析:

最坏情况

定义一类输入,在这类输入下,算法表现出了最坏的运行性能。算法设计人员需要明白,这类输入的共同性质阻止了算法高效地运行,而不只是针对特定的输入。

平均情况

平均情况是表示算法在随机给定的数据上期望的执行情况。通俗地说,一些输入可能会在某些特殊情况下耗费程序大量的时间,但是大部分的输入并不会这样。这个衡量标准描述了用户对算法性能的期望。

最好情况

定义一类输入,算法在这类输入下表现出了最好的运行性能。对于这类输入来说,算法只进行很少的计算。不过在实际情况下,最好情况很少出现。

通过分析三种情况,大致了解了算法的性能,那么接下来你需要为将要面临的问题选择一个算法。

最坏情况

大多数问题都可能会处理一些比n大的数据。任意给定一个n,算法或者程序在处理所有规模为n的数据,其性能可能会动态地发生变化。给定一个程序和n,这个程序的最坏运行时间就是处理所有规模为n的数据所需要的最长运行时间。

我们也看到,最坏情况是对整个世界的一个悲观的分析。但是我们还是非常关注最坏情况,因为:

追根刨底的欲望

这通常是对一个算法复杂度的最早的分析。

实际运行时的限制

如果你需要设计一个系统,协助外科医生进行体外循环心脏手术,那么长时间的运行(即使这种情况是不经常发生)当然不可能接受。

更正式地说,如果Sn是数据集合si中规模为n的子集,t表示算法在每一份数据上的运行时间,那么最坏情况下,对于所有si∈Sn,算法在Sn上的运行时间是t(si) 的最大值。我们将在Sn下的最长时间记做Twc(n),Twc(n) 的增长率表示算法在最坏情况下的复杂度。

一般来说,没有足够的资源来计算每一份数据si,然后检查算法在哪份数据上表现最坏。于是,给定算法的描述,算法分析人员总是想方设法地精心准备可能会导致最坏情况的输入数据。

平均情况

现在要设计一个支持n个电话的电话系统,n是一个非常大的数目,要求在最坏情况下,即n/2位用户同时呼叫另外n/2位用户时,这个系统也能够正确地处理数据。虽然这个系统不会由于过载而崩溃,但需要花费过高的代价构造这样的情况。而且,n/2位用户同时呼叫另外n/2位用户发生的概率极小。也许可以设计一个花费较小的系统在过载的情况下很少会(或者从不)崩溃。但是我们还是必需借助数学工具来计算这个概率问题。

对于一个n个样本的数据集合,我们用一个概率分布Pr表示样本的出现概率,单个样本的出现概率为0到1,所有样本的概率的和为1。如果Sn是n个样本的数据集合,那么:

 

如果t表示算法在单个样本的执行时间,那么在Sn上的平均运行时间是:

  

也就是说,在样本si的实际执行时间,t(si) 将会与概率加权。如果Pr{si}=0,那么t(si) 的实际值将不会影响程序的期望运行时间。我们用Tac(n) 表示算法在Sn上的平均运行时间,那么Tac(n) 的增长率表示算法在平均情况下的复杂度。

回忆一下,当我们描述时间或者工作量的增长率时,我们一直忽视了常数,所以我们认为顺序搜索n个元素的平均情况为:

  

探测(符合我们之前的假设),按照惯例,在符合这些假设的前提下,期望顺序搜索能够处理线性或者是n阶的元素。

最好情况

知道算法的最好情况是非常有用的,即便这种情况很少发生。在很多情况下,最好情况能让我们看到算法的最优状况。例如,线性搜索的最好情况是当它在n个元素中搜索v的时候,第一个元素恰好就是要找的那个。一个稍微有些不同的算法,我们叫做计数搜索(Counting Search),在n个元素中搜索v,并且记录v在表中出现的次数。如果v的计数是0,那么这个值是不存在的,所以会返回false,否则返回 true。注意,计数搜索总是会搜索整个表,因此,它的最坏情况是O(n)(和顺序搜索一样),最好情况还是O(n),所以我们不能够使用这个算法,因为它的最好或者平均情况没有改善性能。

最好最坏和平均情况下的性能分析相关推荐

  1. 最好、最坏、平均、均摊时间复杂度分析

    1.最好.最坏.平均情况时间复杂度 有时候我们分析一段代码的时间复杂度时,并不能很直观的就得出结果,需要结合具体的场合来判断它的平均情况.下面来看一个栗子: /*** 找出给定数组中给定元素的位置,如 ...

  2. Linux系统下常见性能分析工具的使用

    在前面的文章中,我简单介绍了影响linux性能的几个方面以及如何解决这些方面的问题,但是如何才能从系统上发现是某个方面或某几个方面出现问题了呢,这就需要使用linux系统提供的几个常用性能分析工具,下 ...

  3. linux 性能教程,Linux系统下常见性能分析工具的使用

    在前面的文章中,我简单介绍了影响linux性能的几个方面以及如何解决这些方面的问题,但是如何才能从系统上发现是某个方面或某几个方面出现问题了呢,这就需要使用linux系统提供的几个常用性能分析工具,下 ...

  4. 分析linux系统的运行性能,Linux系统下常见性能分析工具的使用

    在前面的文章中,我简单介绍了影响linux性能的几个方面以及如何解决这些方面的问题,但是如何才能从系统上发现是某个方面或某几个方面出现问题了呢,这就需要使用linux系统提供的几个常用性能分析工具,下 ...

  5. 算法笔记(二)——浅析最好、最坏、平均、均摊时间分析方法

    为了使时间复杂度评价方法在不同量级情况下,评价更为全面.更精确,于是又可分为以下四种评价方法: (一)最好情况时间复杂度: 即一个程序在最好情况下的时间复杂度,比如,找一个数组中的元素,第一次就找到元 ...

  6. 各排序算法最好最坏平均情况下的时间复杂度

    方式: 平均 最坏 最好 插入 n^2 n^2 n 希尔 n^1.3 / / 冒泡 n^2 n^2 n 快速 nlogn n^2 nlogn 选择 n^2 n^2 n^2 堆排 nlogn nlogn ...

  7. 粗略的看下两款Linux下的性能分析工具

    uptime -> 查询系统负载信息 我们先执行下uptime命令看下: uptime 以逗号分隔我们可以看到第一段是 # 16:03:53 => 系统当前的时间 # up 4:25 =& ...

  8. 自定义类加载器在复杂类加载情况下的运行分析

    在之前咱们都在研究自定义类加载器的一些东东,不过接一来的学习还会依托于之前咱们写的MyTest16这个自定义类加载器,这里先再回顾一下: public class MyTest16 extends C ...

  9. 随想录(canvas双缓存下的性能分析)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 有过canvas编程经验的同学都知道,如果希望在客户端屏幕上不出现闪烁的情况,最好使用双缓存输出 ...

最新文章

  1. 什么是DCI? 它有什么用?
  2. 适当地使用公共语言运行库的垃圾回收器和自动内存管理
  3. python脚本设置linux环境变量_Linux环境变量export方法与修改文件方法的区别
  4. Keras运行代码时出现的问题及解决方法
  5. 【IM】关于稀疏学习和鲁棒学习的理解
  6. 黑马程序员pink老师前端入门教程,零基础必看的JavaScript基础语法视频教程(三)
  7. Linux下解压:tar、rar、7z命令
  8. 解决方案:数据同步Canal
  9. 笔记本windows7设置WIFI教程(超详细)
  10. 使用as3crypto在Flex中实现AES加密
  11. 游侠原创:VMware ESXi 5安装图文教程
  12. 《态度》- 吴军 四十封启明家书 读后感
  13. mysql 中文脱敏_怎样选择数据库脱敏系统?
  14. Deep Adversarial Decomposition: A Unified Framework for Separating Superimposed Images
  15. 京东商城网页数据爬取
  16. 助力假发线上销售 帕克西3D发型虚拟试戴接入电商平台使用
  17. Flink 创建流处理运行环境
  18. B树的原理及代码实现、B+树和B*树介绍及应用
  19. 面向对象程序设计(c++)面试常问——for考研复试面试
  20. 祖传代码如何优化性能?

热门文章

  1. 【Android 性能优化】布局渲染优化 ( GPU 过度绘制优化总结 | CPU 渲染过程 | Layout Inspector 工具 | View Tree 分析 | 布局组件层级分析 )
  2. 【Netty】Netty 核心组件 ( Future | Channel | Selector | ChannelHandler )
  3. 【Kotlin】Lambda 表达式 ( 简介 | 表达式语法 | 表达式类型 | 表达式返回值 | 调用方式 | 完整示例 )
  4. ls -Slh du -h
  5. Linux下TCP最大连接数受限问题
  6. mybatis_helloword(1)
  7. Homebrew常用命令
  8. 实验四、主存空间的分配和回收模拟
  9. JMM内存模型如何为并发保驾护航
  10. day04-视图/配置文件/静态文件的基本使用