事后统计方法
事后统计方法:
这种方法主要是通过设计好的测试程序和数据,利用计算机计时器对不同算法编制的程序的运行时间进行比较,从而确认算法效率的高低。
但这种算法显然是有很大的缺陷的:
①必须依据算法事先编制好程序,这程序需要花费大量的时间和精力。如果编制出来发现它根本是很糟糕的算法,不是竹篮打水一场空吗?
②时间的比较依赖计算机硬件和软件等环境因素,有时会掩盖算法本身的优劣。
③算法的测试数据设计困难,并且程序的运行时间往往还与测试数据的规模有很大关系,效率高的算法在小的测试数据面前往往得不到体现。
事前分析估算方法
事前分析估算方法:
在计算机程序编制前,依据统计方法对算法进行估算。
一个高级程序语言编写的程序在计算机上运行时所消耗的时间取决于下列因素:
- 算法采用的策略、方法
- 编译产生的代码质量
- 问题的输入规模
- 机器执行指令的速度
(第一条当然是算法好坏的根本,第二条要由软件来支持,第四条要看硬件性能。)
一个程序的运行时间,依赖于算法的好坏和问题的输入规模。所谓问题输入规模是指输入量的多少
两种求和的算法:
第一种算法:
int i, sum=0,n=100; /*执行1次*/
for(i=1;i<=n;i++) /*执行了n+1次*/
{
sum=sum+i; /*执行n次*/
}
printf("%d",sum); /*执行1次*/
第二种算法:
int sum=0,n=100; /*执行一次*/
sum=(1+n)*n/2; /*执行一次*/
printf("%d",sum); /*执行一次*/
显然,第一种算法,执行了1+(n+1)+n+1次=2n+3次;而第二种算法,1+1+1=3 次。事实 两个算法的第一条和最后一条语句是一样的,所以我们关注的代
码其实是中间的那部分,我们把循环看作 个整体,忽略头尾循环判的开销,那么
这两个算法其实就是n次与1次的差距。算法好坏显而易见。
测定运行时间最可靠的方法就是计算对运行时间有消耗的基本操作的执行次数 运行时间与这个计数成正比
在分析程序的运行时间时,最重要的是把程序看成是强立于程序设计语言的算法或一系列步骤。我们在分析一个算法的运行时间时,重要的是把基本操作的数量与输入规模关联起来,即基本操作的数量必须表示成输入规模的函数。
由以上图像说明:随着n值的越来越大,它们在时间效率上的差异也就越来越大
函数的渐近增长
算法A:2n+3次操作 与 算法B:3n+1次操作
输入规模n没有限制的情况下,只要超过一个数值N,这个函数就总是大于另一个函数,我们称函数是渐进增长的。
函数的渐进增长:给定两个函数f(n)和g(n),如果存在一个整数N,使得对于所有的n>N,f(n)总是比g(n)大,那么,我们说f(n)的增长渐近快于g(n)。
算法C:4n+8 与 算法D: 2n^2+1
由以上表格说明:我们可以忽略这些加法常数
算法E: 2n^2+3n+1 与 算法F: 2n^3+3n+1
由以上表格说明:与最高次项相乘的常数并不重要
算法G:2n^2 算法H :3n +1 与 算法I:2n^2+3n+1
由以上表格说明:最高次项的指数大的,函数随着n的增长。如果也会变得增长特别快。
判断一个算法的效率时,函数中的常数和其他次项常常可以忽略,而更应该关注主项(最高次项)的阶数。
某个算法,随着n的增长,他也会越来越优于另一个算法,或者越来越差于另一个算法