算法效率衡量
对于同一问题,我们给出了两种解决算法,在两种算法的实现中,我们对程序执行的时间进行了测算,发现两段程序执行的时间相差悬殊,由此我们可以得出结论:实现算法程序的执行时间可以反映出算法的效率,即算法的优劣。
单靠时间值绝对可信吗?
假设我们将第二次尝试的算法程序运行在一台配置古老性能低下的计算机中,情况会如何呢?很可能运行的时间并不会比在我们电脑中运行算法一的时间快多少。
单纯依靠运行的时间来比较算法的优劣并不一定是客观准确的!
程序的运行离不开计算机环境(包括硬件和操作系统),这些客观原因会影响程序运行的速度并反应在程序的执行时间上,那么如何才能客观的评判一个算法的优劣呢?
时间复杂度与“大O记法”
我们假定计算机执行算法每一个基本操作的时间是固定的一个时间单位,那么有多少个基本操作就代表会花费多少时间单位。虽然对于不同的机器环境,确切的时间单位是不同的,但是对于算法进行多少个基本操作(即花费多少时间单位)在规模数量级上却是相同的,由此可以忽略机器环境的影响而客观的反应算法的时间效率。
对于算法的时间效率,我们可以用“大O记法”来表示
“大O记法”:对于单调的整数函数f,如果存在一个整数函数g和常数c>0,使得对于充分大的n总有f(n)<=c*g(n),就说函数g是f的一个渐近函数(忽略常数),记为f(n)=O(g(n))。也就是说,在趋向无穷的极限意义下,函数f的增长速度受到函数g的约束,亦即函数f与函数g的特征相似。
时间复杂度:假设存在函数g,使得算法A处理规模为n的问题示例所用时间为T(n)=O(g(n)),则称O(g(n))为算法A的渐近时间复杂度,简称时间复杂度,记为T(n)。
如何理解“大O记法”
对于算法进行特别具体细致的分析虽然很好,但在实践中的实际价值有限。对于算法的时间性质和空间性质,最重要的是其数量级和趋势,这些是分析算法效率的主要部分。而计量算法基本操作数量的规模函数中哪些常量因子可以忽略不计。例如,可以认为3n^2和100n^2属于同一个量级,如果两个算法处理同样规模实例时代价分别为这两个函数,就认为它们的效率“差不多”,都为n^2级。
例题:如果a+b+c =1000,且a^2+b^2+c^2(a,b,c为自然数),如何求出所有a,b,c可能的组合?
for a in range(0,1001): for b in range(0,1001): for c in range(0,1001): if a+b+c == 1000 and a**2+b**2 == c**2: print("a,b,c:%d,%d,%d"%(a,b,c))
对上述算法:
T = 1000 *1000*1000*2 (粗略将if和print作为两句,复杂度用2)
若将题目条件改为a+b+c=2000,则:
T=2000*2000*2000*2
若为:a+b+c=n
T =n*n*n*2 (算法的复杂度和规模有关)
T(n)=n^3*2 (忽略常数)
g(n)=n^3
T(n)=kg(n) (k是个常数)
g(n)是T(n)的一个渐进函数,T(n)=O(g(n))=O(n^3)