一.什么是摊还分析?
1.它是一种分析算法的方法,在摊还分析中,我们求数据结构的一个操作序列中所执行的所有操作的平均时间来评价操作的代价。
2.这样我们就可以说明一个操作的平均代价是很低的(即使在某个单一操作的代价很高)。
3.但摊还分析却不同于平均情况分析,它不涉及概率。但可以保证最坏情况下每个操作的平均性能。
二.摊还分析中常用的前两种技术:
一.聚合分析
利用聚合分析,我们证明对所有n,一个n个操作的序列最坏情况下花费的时间为T(n),因此,在最坏情况下的每个操作的摊还代价(平均代价)为T(n)/n.
下面用栈操作来详细分析:
1.PUSH(S,x):将对象x压入栈S中
2.POP(S):将栈S的栈顶对象弹出,并返回该对象。
我们都知道上面两个操作的时间都是O(1),我们假定其代价均为1,那么n个PUSH或POP操作的总代价为n,其时间则为O(n),其平均运行时间为O(1)
现在我们增加一种方法:
3.MULTIPOP(S,k):此方法删除栈S栈顶的k个对象。
我们假设删除一个对象的代价为1
则我们有:
当k=1时,只删除栈顶第一个元素,代价为1
当k=2时,删除栈顶前两个元素,代价为2
当k=3时,代价为3
当k=n时,我们有代价为n
所以:此操作的最坏单个操作代价为n
因此,任意一个栈操作的最坏情况时间为O(n),从而一个n个操作序列的最坏情况代价为O(n^2).
所以对任意一个n值,任意操作花费的时间最多为O(n). 对其中一个操作的平均时间为O(n)/n=O(1).
因此上面三种栈操作的平均代价都为O(1).
我们实际上得出的是一个n个操作的序列最坏情况的运行代价为n,再除以n得到了每个操作的平均代价
二.核算法
核算法中有两个概念:摊还代价和实际代价
摊还代价:用核算法进行摊还分析时,我们对不同的操作赋予的不同的代价,这些代价可能小于或大于其实际代价。
实际代价:操作实际运行时的代价。
信用:当一个操作的摊还代价超出其实际代价时,我们将差额存入数据结构的特定的对象,存入的差额称为信用
信用用来解决后续操作中摊还代价小于实际代价的时候,信用可以用来支付差额。
在核算法中,不同的的操作可能有不同的摊还代价,这种方法不同于聚合分析中所有操作都赋予相同摊还代价的方式。
下面用栈操作进行分析:
操作 | 实际代价 |
---|---|
PUSH | 1 |
POP | 1 |
MULTIPOP(s,k) | min(k,s) |
下面我们为这些操作赋予如下摊还代价:
操作 | 摊还代价 |
---|---|
PUSH | 2 |
POP | 0 |
MULTIPOP(s,k) | 0 |
在上表中PUSH的代价多1,它将分配给POP,由于每个栈中的每个元素都有伴随着1个POP代价,所以对于n个MULTIPOP操作,其代价为n。
所以其总摊还代价为n,实际代价也是。