思考:如果两个算法都满足功能性需求,那工程中最关心的其它特性是什么?如何比较评判呢?
注: 性价比(效率)是工程中最关注的算法附加特性!
算法效率的衡量
事后统计法
- 比较不同算法对同一组输入数据的运行处理时间
缺陷
- 为了获得不同算法的运行时间必须编写相应程序
- 运行时间严重依赖硬件及运行时的环境因素
- 算法的测试数据选取相当困难
事前分析估算
- 依据统计的方法对算法效率进行估算
影响算法效率的主要因素
- 算法采用的策略和方法
- 问题的输入规模
- 编译器所产生的代码
- 计算机执行速度
算法效率的简单估算一
算法效率的简单估算二
算法效率的简单估算三
实例分析:程序效率估算
#include <iostream>
using namespace std;
int func(int a[], int len) // ==> (n*n + 2)
{
int ret = 0; // 1
for(int i=0; i<len; i++)
{
for(int j=0; j<len; j++)
{
ret += a[i] * a[j]; // n * n
}
}
return ret; // 1
}
int main()
{
int array[] = {1, 2, 3, 4, 5};
cout << func(array, 5) << endl;
return 0;
}
#include <iostream>
using namespace std;
long sum1(int n) // ==> (2n + 4)
{
long ret = 0; // 2
int* array = new int[n];
for(int i=0; i<n; i++)
{
array[i] = i + 1; // n
}
for(int i=0; i<n; i++)
{
ret += array[i]; // n
}
delete[] array; // 2
return ret;
}
long sum2(int n) // ==> n + 2
{
long ret = 0; // 1
for(int i=1; i<=n; i++)
{
ret += i; // n
}
return ret; // 1
}
long sum3(int n) // ==> 3
{
long ret = 0; // 1
if( n > 0 )
{
ret = (1 + n) * n / 2; // 1
}
return ret; // 1
}
int main()
{
cout << "sum1(100) = " << sum1(100) << endl;
cout << "sum2(100) = " << sum2(100) << endl;
cout << "sum3(100) = " << sum3(100) << endl;
return 0;
}
启示
- 程序效率估算练习中的关键部分的操作数量为 n * n
- 三种求和算法中关键部分的操作数量分别为 2n,n 和 1
随着问题规模 n 的增大,它们操作数量的差异会越来越大,因此实际算法在效率上的差异也会变得非常明显
算法操作数量的对比一
结论:
- n <= 3 时,算法B(2n2 + 1)优于算法A(4n+8)
- 当 n 越来越大的时候,算法A(4n+8)相对算法B(2b2+1)优势明显
算法操作数量的对比二
结论:
- 当 n == 1 时,算法C(2n2 + 3n + 1) 和算法D(2n3 + 3n + 1) 的操作数量相同
- 当 n 越来越大的时候,算法 C(2n2 + 3n + 1)的效率远高于算法D(2n3 + 3n+ 1)
算法操作数量的对比三
结论:
- 判断一个算法的效率时,操作数量中的常数项和其他次要项常常可以忽略,只需要关注最高阶就能得出结算。
小结
- 算法的度量有事后统计法和事前分析估算法
- 事后统计法不容易准确度量算法的效率
- 事前分析估算法通过操作数量度量算法效率
- 判断一个算法效率时只需要关注最高阶项就能得出结论
注意:某个算法,随着问题规模 n 的增大,它会越来越优越于另一算法,或者越来越差于另一算法。
以上内容整理于狄泰软件学院系列课程,请大家保护原创!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。