http://freelet.blogspot.com/2008/12/amortized-analysis.html
在平攤分析中,執行一系列資料結構操作所需要的時間是通過執行的所有操作求平均而得出的。平攤分析可以用來證明在一系列操作中,通過對所有操作求平均之後,即使其中單一的操作具有較大的代價,平均代價還是很小的。
平攤分析不牽涉到機率, 平攤分析保證在最壞情況下,每個操作具有的平均效能。
三中最常用的技術:
1.聚集分析(aggregate analysis)
證明對所有的n, 由n個操作所構成的序列的總時間在最壞情況下為T(n)
例子:
棧操作
PUSH(S, x):將x壓入S
POP(S):彈出棧頂
MULTIPOP(S, k):彈出棧頂k個對象
由n個PUSH, POP和MULTIPOP操作序列,其作用於一個初始為空白的棧。
分析:每個操作的最壞情況時間是O(n). 因此n個操作的序列的代價是O (n2)
雖然這一分析正確,但這個界不夠緊確,利用聚集分析,可以獲得更好的上界。
一個對象在每次被壓入棧後,至多被彈出一次。所以,調用POP(包括MULTIPOP)的次數至多等於PUSH的次數,即至多為n.。對任意的n,包含n個PUSH, POP, MULTIPOP操作的序列的總時間為O(n). 每個操作的平均代價為O(n) / n = O(1).。 聚集分析中,將每個操作的平攤代價指派為平均代價。所以三個棧操作的平攤代價都是O(1)。
2.記帳方法
在平攤分析的記帳方法中,對不同的操作賦予不同的費用,某些操作的費用比它們的實際代價或多或少。
我們對一個操作的收費的數量稱為平攤代價。當一個操作的平攤代價超過了它的實際代價時,兩者的差值就被當作存款(credit),並賦予資料結構中的一些特定對象,可以用來補償那些平攤代價低於其實際代價的操作。這種方法與聚集分析不同的是,對後者,所有操作都具有相同的平攤代價。
資料結構中儲存的總存款等於總的平攤代價和總的實際代價之差。注意:總存款不能是負的。
例子:棧操作
實際代價:
PUSH 1
POP 1
MULTIPOP min(k, s)
現在對它們賦予以下的平攤代價:
PUSH: 2
POP: 0
MULTIPOP 0
假設用1元錢來表示代價的單位。開始時棧時空的。
棧資料結構與餐廳中一堆疊放的盤子類似。當把一個盤子壓入棧時,用1元錢來支付該動作的實際代價,還有1元的存款,將其放在盤子的頂上。盤子上面的錢時用來預付將盤子從棧中彈出所需代價的。當執行一個POP操作時,對該操作不收取任何費用,只需用盤中存放的存款來支付其實際代價即可。同理,也無需對MULTIPOP收取任何費用。
因為棧上的每個盤子上面都有1元錢,而且棧中總有非負個數的盤子。這就保證了存款的總量總是非負的。這樣,對任意的包含n次PUSH, POP, MULTIPOP操作的序列,總的平攤代價就是總的實際代價的一個上界。總的平攤代價為O(n), 故總的實際代價也為O(n).
3.勢能方法
在平攤分析中,勢能方法(potential method)不是將已預付的工作作為存在資料結構特定對象中存款來表示,而是表示成一 種“勢能”或“勢”,它在需要時可以釋放出來,以支付後面的操作。勢是與整個資料結構而不是其中的個別對象發生聯絡的。
對一個初始資料結構D0 執行n個操作。對每個i,設ci為每個操作的實際代價,
Di 為對資料結構Di-1執行第i個操作的結果. 勢函數Φ 將每個資料結構Di 映射為一個實數Φ(Di), 即與Di相聯絡的勢. 第i個操作的平攤代價ai根據勢函數Φ 定義為
ai = ci + Φ(Di) - Φ(Di-1)
每個操作的平攤代價為其實際代價ci加上由於該操作所增加的勢。
n個操作的總的平攤代價為
∑ai = ∑ci +Φ(Dn) - Φ(D0)
如果我們能定義一個勢函數Φ使得對所有n,有Φ(Dn) ≥ Φ(D0), 則總的平攤代價∑ai就是總的實際代價∑ci的一個上界。通常為了方便起見定義Φ(D0) = 0。
直觀上看,如果第i個操作的勢差Φ(Di) - Φ(Di-1)是正的,則平攤代價ai表示對第i個操作多收了費,同時資料結構的勢也隨之增加了。如果勢差是負值,則平攤代價就表示對第i個操作的不足收費,這是通過減少勢來支付該操作的實際代價。
平攤代價依賴於所選擇的勢函數Φ。不同的勢函數可能會產生不同的平攤代價,但它們都是實際代價的上界。最佳勢函數的選擇取決於所需的時間界。
例子:棧操作
定義棧上的勢函數Φ為棧中對象的個數。開始時要處理的空棧D0,且Φ(D0)=0。因為棧中的對象數始終時非負的,故在第i個操作後,棧Di就具有非負的勢。
以Φ表示的n個操作的平攤代價的總和就表示了總的實際代價的一個上界。
現在計算各個操作的平攤代價。
如果作用於一個包含s個對象的棧上的第i個操作是PUSH:
則勢差為Φ(Di) - Φ(Di-1) = (s+1) – s = 1
這個PUSH操作的平攤代價為ai = ci + Φ(Di) - Φ(Di-1) = 1+1=2
假設棧上的第i個操作是MULTIPOP(S, k). 該操作的實際代價為min(s, k).
勢差為Φ(Di) - Φ(Di-1) = - min(s, k)
因此MULTIPOP操作的平攤代價為
ai = ci + Φ(Di) - Φ(Di-1) = min(s, k) - min(s, k) = 0
類似POP操作的平攤代價也是0。
三中棧操作的每一種的平攤代價都是O(1), 這樣包含n個操作的序列的總平攤代價就是O(n)。已經證明n個操作的平攤代價的總和是總的實際代價的一個上界。所以n個操作的最壞情況代價為O(n).
例子:
動態表,當向滿的表插入一項時,將表擴大一倍,但當刪除一項而引起表不足1/4滿時(不是1/2),就將表縮寫為原來的一半。
可以利用平攤分析,證明插入和刪除操作的平攤代價均為O(1).