算法-第2章-算法效率分析基础(李静)
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2.2.2 符号О
定义1 我们把函数t(n)属于O(g(n)) ,记作t(n) ∈ O(g(n)) ; 它的成立条件是:对于所有足够大的n, t(n) 的上界由g(n) 的常数倍数所确定,也就是说,存在大于0的常数c和非负 的整数n0,使得: 对于所有的n≥ n0来说, t(n) ≤c g(n)
cg(n)
思考
• • • • P46 2T P46 4.bT P46 5T P46 6.aT
补充知识
• 渐近分析中函数比较
– f(n)∈ O(g(n)) a b; – f(n)∈ (g(n)) a b; – f(n)∈ (g(n)) a = b; – f(n)∈ o(g(n)) a < b; – f(n)∈ (g(n)) a > b.
• 无论是最差效率分析还是最优效率分析都不能提供一 种必要的信息:在“典型”或者“随机”输入的情况 下, 一个算法会具有什么样的行为。这正是平均效率 试图提供给我们信息。 • 摊销效率: 它并不适用于算法的单次运行,而是应用于 算法对同样数据结构所执行的一系列操作。
2.1.4 算法的最优、最差和平均效率
对于两个连续执行部分组成的算法,应该如何应 用这个特性呢?它意味着该算法的整体效率是由 具有较大的增长次数的部分所决定的,即它的效 率较差的部分.
பைடு நூலகம்
算法分析:加法规则
t(n, m)=t1(n)+t2 (m) ∈O(max (f (n), g (m)))
两个并列循环的例子 void example (float x[ ][ ], int m, int n, int k) { float sum [ ]; for ( int i=0; i<m; i++ ) { //x[][]中各行 sum[i] = 0.0; //数据累加 for ( int j=0; j<n; j++ ) sum[i]+=x[i][j]; } for ( i = 0; i < m; i++ ) //打印各行数据和 cout << “Line ” << i << “ : ” <<sum [i] << endl; } 渐进时间复杂度为O(max (m*n, m))
2.1 分析框架
• 在本节中,我们将概要地描述一个分析算法效 率的一般性框架.首先必须指出,有两种算法 效率:时间效率和空间效率。
–时间效率指出正在讨论的算法运行得有多快; –空间效率关心算法需要的额外空间。
2.1 分析框架
• 研究实验告诉我们,对于大多数问题来 说,我们在速度上能够取得的进展要远 大于在空间上的进展,所以我们把主要 精力集中在时间效率上。 • 时间和空间可以相互转化。
(2)反身性:
(3)对称性:
– f(n)∈ (g(n)) g(n)∈ (f(n)) .
(4)互对称性:
– f(n)∈ O(g(n)) g(n)∈ (f(n)) ; – f(n)∈ o(g(n)) g(n)∈ (f(n)) ;
思考题
• P47 Problem 10 • P52 Problem 4
T (n) copC(n)
2.1.3增长次数
为什么对于大规模的输入要强调执行次数的增长次 数呢?这是因为小规模输入在运行时间上差别不足以将 高效的算法和低效的算法法区分开来。
Performance Analysis
60
2n
n2
50
40
n log n
30
f
20
10
n Log n
0
0
1
2
3
4
n
5
(1)传递性:
– f(n)∈ o(g(n)), g(n)∈ o(h(n)) f(n)∈ o(h(n));
– f(n)∈ (g(n)), g(n)∈ (h(n)) f(n)∈ (h(n));
•
渐近分析记号的若干性
– f(n)∈ (f(n));
– f(n)∈ O(f(n)); – f(n)∈ (f(n)).
算法的评价
• 1.正确性
– 正确性是指算法的执行结果应该满足预先规定的功能和性能 要求
• 2.可读性
– 一个算法应该思路清晰、层次分明、简单明了、易读易懂
• 3.健壮性
– 算法的健壮性指的是,算法应对非法输入的数据做出恰当反 映或进行相应处理
• 4.复杂性
– 算法的复杂性是算法效率的度量,是评价算法优劣的重要依 据 ,算法的复杂性有时间复杂性和空间复杂性之分
t(n) cg(n)
n0之前的情 况无关重要
n n0 符号Ω:t(n)∈Ω(g(n))
2.2.4 符号Θ
定义 3 我们把函数t(n)属于Θ(g(n)) ,记作t(n) ∈Θ(g(n)) ; 它的成立条件是:对于所有足够大的n, t(n) 的上界和下 界都由g(n)的常数倍数所确定,也就是说,存在大于0的 常数c1,c2和和非负的整数n0,使得: 对于所有的n≥ n0来说, c2g(n) ≤t(n) ≤ c1g(n)
表明t (n)的增长次数比g (n)小 表明t (n)的增长次数和g (n)相同 表明t (n)的增长次数比g (n)大
The Big-O and Related Notations
2.2.7 基本的效率类型
1 log n n n log n n2 n3 2n n! constant logarithmic linear n log n quadratic cubic exponential factorial
2.2.5 渐进符号的有用特性—乘法规则
t(n, m) = t1(n)*t2 (m) ∈ O(f (n)*g(m))
例:求两个方阵的乘积 C=A*B #define n 自然数 MATRIXMLT(float A[n][n],float B[n][n],float C[n][n]) { int i,j,k; for(i=0;i<n;i++) //n for(j=0;j<n;j++) { //n*n O(n) C[i][j]=0; //n*n O(n) O(n) for( k=0;k<n;k++) //n*n*n C[i][j]=A[i][k]*B[k][j] //n*n*n } } t(n) n3 O(n3 )
2.2 渐进符号和基本效率类型
2.2.1 非正式的介绍
O(g(n)) 是增长次数小于等于g(n) (以及其常数倍,n趋 向于无穷大)的函数集合。 n∈O(n2),100n+5∈O(n2), n(n-1) /2 ∈O(n2),n3∈/ O(n2), Ω(g(n)),代表增长次数大于等于g(n)(以及其常数倍,n趋 向于无穷大)的函数集合。 n3∈ Ω(n2), n(n-1) /2 ∈ Ω(n2),但是100n+5 ∈/ Ω(n2) Θ(g(n))是增长次数等于g(n) )(以及其常数倍,n趋向于无 穷大)的函数集合。因此,每一个二次方程an2+bn+c在 a>0的情况下都包含在Θ(n2)中,除了无数类似于n2+sin n和n2+log n的函数(你能解释原因吗?)。
• 如何确定基本操作呢? 由于做每一次循环都会进行一次比较, 所以把比较作为基本操作 if A[i]>maxval
我们把C(n)记作比较运算的执行次数,并试图寻找一个公式 将它表达为规模n的函数。由于该算法每执行一次循环就会 做一次比较,并且对于循环变量i在1和n-1(包含在内)中的 每个值都会做一次循环,所以,我们得到C(n)的下列求和 表达式:
• 最差效率 Cworst(n)=n • 最优效率 Cbest(n)=1 • 平均效率 Cavg(n)
2.1.5 分析框架概要
• 算法的时间效率和空间效率都用输入规模的函数进行度量。 • 用算法基本操作的执行次数来度量时间效率。 • 通过计算算法消耗的额外存储单元的数量来度量空间效率。 • 对于输入规模相同的不同输入数据,有些算法的效率会有 显著差异。对于这样的算法,我们需要区分最差效率,平 均效率和最优效率。 • 本框架主要关心,当算法的输入规模趋向于无限大的时候, 其运行时间(消耗的额外空间)函数的增长次数。
第2章 算法效率分析基础
我常常说,当你对所讲的内容能够进行度 量并且能够用数字来表达时,证明你对这些内
容是有所了解的;如果你不能用数字来表达,
那么你的认识是不完整的,也是无法令人满意 的. -------Lord Kelvin(1824-1907)
算法的特征
• (1)可行性:针对实际问题设计的算法,人们总是希 望能够得到满意的结果。 • (2)确定性:算法的确定性,是指算法中的每一个步 骤都必须是有明确定义的,不允许有模棱两可的解释 ,也不允许有多义性。 • (3)有穷性:算法的有穷性,是指算法必须能在有限 的时间内做完,即算法必须能在执行有限个步骤之后 终止。 • (4)输入:通常,算法中的各种运算总是要施加到各 个运算对象上,而这些运算对象又可能具有某种初始 状态,这是算法执行的起点或是依据。 • (5)输出:一个算法有一个或多个输出,以反映对输 入数据加工后的结果。
•
渐近分析记号的若干性质
– f(n)∈ (g(n)), g(n)∈ (h(n)) f(n)∈ (h(n)); – f(n)∈ O(g(n)), g(n)∈ O (h(n)) f(n)∈ O (h(n)); – f(n)∈ (g(n)), g(n)∈ (h(n)) f(n)∈ (h(n));
2.1.1 输入规模的度量 • 几乎所有的算法,对于规模更大的输入 都需要动行更长的时间。例如,需要更 多时间来对更长的数组排序,更大的矩 阵相乘也需要花费更多时间,等等。 • 所以,使用一个以算法输入规模n为参数 的函数,来研究算法效率是非常合乎逻 辑的。
2.1.2 运行时间的度量单位
A. 把基本操作作为算法运行时间的度量单位。
2.2.6 利用极限比较增长次数
• 虽然符号O, Ω和Θ的正式定义对于证明它们的抽象性 质是不可缺少的,但我们很少直接用它们来比较两个 特定函数的增长次数。 • 有一种较为简便的比较方法,它是基于对所计论的两 个函数的比率求极限。有3种极限情况会发生:
0 lim t (n) c n g ( n)
t(n)
n0之前的情 况无关重要
n
n0
符号O:t(n)∈O(g(n))
2.2.3 符号Ω
定义2 我们把函数t(n)属于Ω(g(n)) ,记作t(n)∈Ω(g(n)) 它的成立条件是:对于所有足够大的n, t(n)的下界由g(n) 的常数倍所确定,也就是说,存在大于0的常数c和非负 的整数n0,使得: 对于所有的n≥ n0来说, t(n) ≥c g(n)
c1 g(n)
n0之前的情 况无关重要
t(n) c2 g(n)
n n0 符号Θ:t(n)∈Θ(g(n))
2.2.5 渐进符号的有用特性—加法规则
定理:如果t1(n) ∈O(g1(n))并且t2(n) ∈O(g2(n)),则 t1(n)+ t2(n)∈O(max{g1(n), g2(n)}) (对于Ω和Θ符号, 类似的断言也为真)
6
7
8
9
10
练习
• P40 8T
答案
2.1.4 算法的最优、最差和平均效率
• 一个算法的最差效率是指当输入规模为n时,算法在最 坏情况下的效率。
– 这时,相对于其他规模为n的输入,该算法的运行时间最长。
• 一个算法的最优效率是指当输入规模为n时,算法在最 优情况下的效率。
– 这时,与其它规模为n的输入相比,该算法运行得最快。
• 所谓基本操作,就是算法中最重要的操作。它 们对总运行时间的贡献最大。 B. 计算基本操作的运行次数。 • 掌握了这样一种规律,就不难发现一个算法中 的基本操作:它通常是算法最内层循环中最费 时的操作。例如,大多数排序算法是通过比较 列表中的待排序元素(键)来进行工作的;对 于这种算法来说,基本操作就是对键的比较。
2.3 非递归算法的数学分析
例1 :考虑一下从n个元素的列表中查找元素最大值的问题. 简单起见,我们假设列表是用数组实现的。下面给出一个 解决问题的标准算法的伪代码。 算法 MaxElement(A[0..n-1]) //求给定数组中最大元素的值 //输入:实数数组A[0..n-1] //输出:A中最大元素的值 maxval←A[0] for i←1 to n-1 do if A[i]>maxval maxval←A[i] return maxval