标签:exp 分析 复杂度 dao 存在 open const def +=
为什么要了解算法的效率?
一般来说,编程就是把各种已知的算法代入到自己的代码当中,以此来解决问题。因此,了解各种算法的效率对于我们选择一个合适的算法有很大帮助。
算法的效率由什么确定?
从算法分析的理论来讲,算法的效率通常由它们的复杂度来评估,用渐近记号(asymptotic notation)来表示,通常有 O、 Θ和Ω 记号法。渐进的意思就是当问题的规模变大时,解决这个问题所耗费的时间增加了多少。
(注:当规模较小时,无论是高效的算法还是低效的算法,时间耗费差距不明显,很可能产生误导的结果。所以算法分析针对大规模输入。)
如何测量算法的效率?
一个算法是由控制结构(顺序、分支和循环3种)和基本操作(指固有数据类型的操作)构成的,算法的运行时间与算法中语句的执行次数成正比例,某个算法中语句执行次数多,它运行花费的时间就多。比较同一个问题的不同算法的效率,通常的做法是,选取该算法的基本操作,以其基本操作的重复执行次数作为算法的时间量度,记为时间频度T(n)。n为问题的规模,当n不断变化时,T(n)也会不断变化。一般情况下,算法中重复执行基本操作的次数是问题规模n的某个函数,用T(n)表示。若有某个辅助函数f(n),当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数,记作T(n)=O(f(n))。称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。
算法运行的几种情况(以在一个有n个元素的数列中查找某个元素为例):
在实际使用中,我们一般仅考量算法在最坏情况下的运行情况,也就是对于规模为 n 的输入,算法的最长运行时间。这样做的理由是:
大O记号法(big O notation,O代表omicron,为希腊字母第15个字)的定义:
对于规模为 n的输入,当n增大时,运行这个函数所增加的耗费时间的上界。
算法复杂度的类型:
其他还有O(n3)三次方复杂度,O(n!)阶乘复杂度等等。
用例子来说明不同类型的算法复杂度:
假设我们现在要自己写一段代码来计算ab的结果(b为正整数)。
方法一:
def exp1(a,b): ans=1 while b>0: ans*=a b-=1 return ans
此算法基本步骤为:3b+2步(每个循环里面有3步,一共循环b次,再加上初始ans赋值和返回ans值这两步)。当b足够大时,其他数字都不重要了,因此这个算法是一个线性复杂度的算法。
方法二:
def exp2(a,b): if b==1: return a return a*exp2(a,b-1)
此算法基本步骤为:3b-1步(此处省略推算过程,具体可见参考视频第12分钟处)。因此这个算法也是一个线性复杂度的算法。
方法三:
def exp3(a,b): if b==1: return a if b%2==0: # 如果b是偶数 return (a*a)**(b/2) else: # 如果b是奇数,a的b次方等于a*a**(b-1) return a*exp3(a,b-1)
此算法基本步骤为:log b步(此处省略推算过程,具体可见参考视频第17分钟处)。因此这个算法是一个对数复杂度的算法。
方法四:
def exp4(a,b): ans=0 for i in range(a): for j in range (b): ans+=1 return ans
此算法基本步骤为:b2步(此处省略推算过程,具体可见参考视频第20分钟处)。因此这个算法是一个二次方复杂度的算法。
不同类型算法复杂度的时间增长对比:
O(1) --- 输入增大10倍,解决问题的时间不变
O(n) --- 输入增大10倍,解决问题的时间相应增大10倍
O(log n) --- 输入增大10倍,解决问题的时间相应增大1倍
O(n2) --- 输入增大10倍,解决问题的时间相应增大100倍
参考:麻省理工学院公开课:计算机科学及编程导论 (第8课)
用大O记号法测量算法的效率(Algorithm efficiency Asymptotic notation Big O notation)
标签:exp 分析 复杂度 dao 存在 open const def +=
原文地址:http://www.cnblogs.com/HuZihu/p/7614460.html