python算法的效率通过什么来度量_python04--算法的代价及其度量(P14)

1.把算法的代价看作规模的函数之后,很容易看到一种必然出现的情况:

可能有一些算法,随着实例规模的增长,其时间(或空间)开销的增长非常快,

而另一些算法的开销函数随着规模增长而增长的比较慢,

这两个函数关系称为算法的时间代价和空间代价。

2.人们主要关注算法的最坏情况代价,有时也关注算法的平均代价,而算法的最乐观的估计基本上没有价值。

3.对于算法的时间和空间性质,最重要的是其量级和趋势,这些是代价的主要部分。

例如:可以认为3n²和100n²属于同一个量级

4.”大O记法“

假设存在函数g,使得算法A处理规模为n的问题实例所用的时间T(n)=O(g(n)),则称O(g(n))为算法A的渐进时间复杂度,简称时间复杂度。

算法的空间复杂度S(n)的定义与此类似。S(n)=O(g(n) )

最常用的渐进复杂度函数:

O(1),O(log n),O(n),O(n log n),O(n²),O(n³),O(2n)

5.基本循环程序

这里只考虑算法的时间复杂度,基本循环程序只有顺序组合,条件分支和循环结构。

分析算法的几条基本计算规则:

0.基本操作,认为其时间复杂度为O(1)。如果是函数调用,应该将其时间复杂度代入,参与整体时间复杂度的计算。

(1)加法规则(顺序组合)。如果算法(或所考虑算法片段)是两个部分(或多个部分)的顺序组合,其复杂性是这两部分(或多部分)的复杂性之和。以两个部分为例:

T(n) = T1(n)+T2(n) = O(T1(n))+O(T2(n)) = O(max(T1(n),T2(n)))

其中T1(n)和T2(n)分别为顺序组合的两个部分的时间复杂度。由于忽略了常量因子,加法等价于求最大值,取T1(n)和T2(n)中复杂度较高的一个。

(2)乘法规则(循环结构)。如果算法(或所考虑的算法片段)是一个循环,循环体将执行T1(n)次,每次执行需要T2(n)时间,那么:

T(n) = T1(n) * T2(n) = O(T1(n))*O(T2(n)) = O(T1(n) * T2(n))

(3)取最大规则(分支结构)。如果算法(或所考虑算法片段)是条件分支,两个分支的时间复杂性分别为T1(n)和T2(n),则有:

T(n) = O(max(T1(n),T2(n)))

几个例子:

for i inrange(n):for j inrange(n):

x= 0.0

for k inrange(n):

x= x + m1[i][k] *m2[k][j]

m[i][j]= x

时间复杂度为:

T(n) = O(n)*O(n)*(O(1)+O(n)*O(1)+O(1))

= O(n)*O(n)*O(n)

= O(n*n*n)

= O(n³)

data=[]while还有数据:

x=下一数据

data.insert(0,x)#表新数据加到表的最前面

时间复杂度为:

T(n) = O(1)+O(n)*(O(1)+O(n))

= O(n²)

data=[]while还有数据:

x=下一数据

data.insert(len(data),x)#表新数据加到表的最后面,或写data.append(x)

时间复杂度为:

T(n)= O(1)+O(n)*(O(1)+O(1))= O(n)

6.时间开销

构造新结构,如构造新的list、set等。

构造新的空结构(空表、空集合等)是常量时间操作,

而构造一个包含n个元素的结构,则至少需要O(n)时间。

一些list操作的效率:

表元素访问和元素修改是常量时间操作,

但一般的加入、删除元素操作(即使只加入一个元素)都是O(n)时间操作。

字典dict操作的效率:

主要操作是加入新的关键码-值对和基于关键码查找关联值。

它们的最坏情况复杂度是O(n),但平均复杂度是O(1)。

也就是说,一般而言字典操作的效率很高,但偶尔也会出现效率低的情况。

空间开销

在程序里使用任何类型的对象,都需要付出空间的代价。建立一个表或者元组,至少要占用元素个数那么多空间,即O(n)的存储空间,如果元素也是新创建的,还需要考虑元素本身的存储开销。

集合和字典需要支持快速查询等操作,其结构更加复杂。包含n个元素的集合或字典,至少需要占用O(n)的存储空间。

【注意】

python中的各种组合数据对象都没有预设的最大元素个数。在实际使用中,这些结构能根据元素个数的增长自动扩充存储空间。从空间占用的角度看,其实际开销在存续期间可能变大,但通常不会自动缩小(即使后来元素变得很少了)。举个例子,假设程序里建了个表,而后不断加入元素导致表变得很大,而后又不断删除元素,后来表中元素变得很少,但占用的存储空间并不减少。

还应该注意pyhton自动存储管理系统的影响。举个例子:如果在程序里建立了一个表,此后一直将其作为某个全局变量的值,这个对象就会始终存在并占用空间。如果将其作为函数里局部变量的值,或者虽然作为全局变量的值,但后来通过赋值将其抛弃,这个表对象就可以被回收。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值