算法导论笔记:17摊还分析
? ? ? ?在攤還分析中,通過求數據結構的一系列的操作的平均時間,來評價操作的代價。這樣,即使這些操作中的某個單一操作的代價很高,也可以證明平均代價很低。攤還分析不涉及概率,它可以保證最壞情況下每個操作的平均性能。
?
?????? 攤還分析有三種常用的技術:
? ? ???聚合分析,它確定n個操作的總代價的上界為T(n),所以每個操作的平均代價為T(n)/n。每個操作都有相同的攤還代價。
? ? ???核算法:分析每個操作的攤還代價,不同于聚合分析,每種操作的攤還代價是不同的,核算法將序列中較早的操作的余額作為“信用”儲存起來,與數據結構中的特定對象相關聯,在隨后的操作中,儲存的信用可以用來進行支付。
? ? ???勢能法,與核算法類似,也是分析每個操作的代價,但將勢能作為一個整體存儲,而與數據結構中的某個對象無關。
一:聚合分析
?????? 聚合分析是證明n個操作的最壞情況下的總時間為T(n),因而每個操作的平均代價(聚合代價)為T(n)/n。所以,聚合分析中的每個操作的聚合代價都是相同的。下面以棧操作和二進制計數器為例說明:
??????
?????? 1:棧操作
?????? 棧操作有PUSH和POP,兩個操作的都是O(1)時間的。現在增加一種新的操作MULITIPOP(S, k),該操作刪除棧頂的k個元素,如果k > S.size,則刪除所有元素。該操作與實際執行的POP次數呈線性關系,代碼如下:
MULTIPOP(S, k)
?????? while not STACK-EMPTY(S) and k>0
????????????? POP(S)
????????????? k = k-1
?
因此,MULTIPOP的代價為min(s, k),其中s表示S.size。
?
?????? 因為棧的大小最大為n,所以MULTIPOP的最壞情況為O(n),所以,由n個PUSH,POP,MULTIPOP組成的操作序列的最壞代價為O( n^2),因為序列可能包含O(n)個操作序列。
?
?????? 上面的分析給出的界并不是緊確界,實際上,在一個空棧上執行n個PUSH, POP, MULTIPOP的操作序列,代價最多為O(n)。這是因為,當一個對象壓入棧后,至多將其彈出一次。所以,對于一個非空的棧,可以執行的POP的次數(包含MULTIPOP中的POP)最多與PUSH操作次數一樣,即n次。所以,對任意的n,任意一個由n個PUSH, POP, MULTIPOP組成的操作序列,最多花費O(n)。所以,每個操作的攤還代價為O(1)。
?
2:二進制計數器遞增
?????? 用一個數組A[0..k-1]表示一個k位二進制數x,x的最低位存儲在A[0]中,最高位在A[k-1]中,初始情況下x=0。遞增代碼如下:
INCREMENT(A)
?????? i=0
?????? while i < A.length and A[i] == 1
????????????? A[i] = 0
????????????? i = i+1
?????? if i< A.length
????????????? A[i]= 1
?
?????? 每次INCREMENT操作的代價,與翻轉的二進制位的數目呈線性關系。下圖顯示了將一個二進制數遞增16次的情況,初始值為0,最終變為16:
?
?????? 最壞情況下,INCREMENT執行一次需要花費Θ(k)時間,因此,初始值為0的計數器執行n個INCREMENT操作的最壞情況花費為O(nk)時間。
?
?????? 所以,對于一個初始值為0的計數器,執行n個INCREMENT操作序列最壞情況下時間為O(n),所以,每個操作的攤還代價為O(1)。
?
二:核算法
?????? 核算法,對不同的操作賦予不同的費用,這個費用就是攤還代價。當一個操作的攤還代價超過實際代價的時候,將差額存入數據結構中的特定對象,存入的差額稱為信用。對于后續操作中,攤還代價小于實際代價的情況,信用可以用來支付差額。
?????? 因為希望通過分析攤還代價來說明每個操作的平均代價的很小,所以應該確保n個操作序列的攤還代價是實際代價的上界。如果 表示第i個操作的真實代價,而 表示攤還代價,則對于任意的n,有: ? 。因為信用就是攤還代價和實際代價的差值,即 ? ,所以需要保持數據結構中的總信用永遠為非負值。
?
1:棧操作
?????? 棧操作的實際代價如下:PUSH?? 1;??? POP?????? 1;??? MULTIPOP??? min(k,s)。為這些操作賦予的攤還代價為:????? PUSH?? 2;??? POP?????? 0; MULTIPOP??? 0。
?
?????? 下面證明,如果按照攤還代價進行繳費,則可以支付任意的n個棧操作序列。在PUSH操作時,共繳費2美元,其中1美元支付PUSH的實際代價,將剩余的1美元存入插入的元素,作為信用。這樣,每個插入的元素都具有1美元的信用。這1美元的信用,實際上是用來支付POP操作的預付費。當執行一個POP的時候,并不繳額外的費用,而是使用信用來支付實際代價。MULTIPOP也一樣。所以,對任意的n個PUSH, POP, MULTIPOP組成的序列,總攤還代價為實際代價的上界,總攤還代價為O(n)。
?
2:二進制計數器遞增
?????? INCREMENT的操作時間與實際翻轉的位數成正比,所以可以用翻轉的位數作為操作的實際代價。
?????? 在攤還分析中,對一次置位操作(0->1),繳費2美元,用1美元支付置位操作的實際代價,另存1美元在該位,作為信用,用來支付將來的復位操作(1->0)。所以,任何時刻,計數器中任何為1的位都存有1美元的信用。對于復位操作,無須繳納任何費用。
?????? 所以,每個INCREMENT操作最多置位一次,因此攤還代價為2美元。所以,n個INCREMENT操作,總攤還代價為O(n)。
?
三:勢能法
?????? 勢能法與核算法類似,但是勢能法并不將預付代價表示為數據結構中特定對象的信用,而是表示為“勢能”。勢能是與整個數據結構相關聯,而不是某個特定的對象。將勢能釋放,就可以支付未來操作的代價。
?
?????? 勢能法如下:對一個初始數據結構 執行n個操作。對于i = 1, 2,...,n, 表示第i個操作的實際代價, 表示在數據結構 上執行第i個操作得到的數據結構。勢函數 將每個數據結構 映射到一個實數 ,這個值就是關聯到數據結構 的勢。所以,第i個操作的攤還代價為。每個操作的攤還代價等于其實際代價加上此操作引起的勢能變化。
?
?
轉載于:https://www.cnblogs.com/gqtcgq/p/7247227.html
總結
以上是生活随笔為你收集整理的算法导论笔记:17摊还分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java高效读取大文件
- 下一篇: android转IOS开发学习计划