分攤分析介紹

2021-06-22 18:40:53 字數 1419 閱讀 1985

分攤分析[1]給我的印象是大概是心理安慰,讓我們放心的用,而不去擔心會有什麼壞的效能問題。比如c++ 的vector 動態增長,每個操作的分攤時間複雜度是o(3)。

有三種操作手法:

聚類方法

最壞情形下,一系列操作總的代價上界除以操作個數,就是每個操作的分攤代價。

這裡每個操作的分攤代價相同。

例子 二進位制計數器

inc(a)

i = 0

while i < a.length and a[i] == 1

a[i] = 0

i = i + 1

if i < a.length

a[i] = 1

初始時a[0..k] = 0.

inc(a)最壞是o(k), n次inc最壞達到o(nk)。

但是我們注意不是每次都o(k),只是全一時才這樣。

我們來數字元位翻轉的次數。第0位翻轉了n次,

第1位翻轉了n/2次,總共< 2n。每個inc的分攤代價是o(2)。

記賬方法

每種操作型別分攤代價可能不同,高於實際代價的差值稱為prepaid credit。

例子 push,pop,multipop(k)的實際代價分別是1,1,min(k,s),

而賦予分攤代價分別為2,0,0。當push時,消耗1,剩餘的1存入該物件,當pop時,

使用該物件上存入的1。

勢能方法

把credit當成整個資料結構的勢能,而不是單個樹據物件的。

例1 紅黑樹重建的代價

rb_insert/rb_delete 首先需要o(lgn)查詢到key所在節點,然後只分別需要o(1)的節點插入,節點刪除和旋轉,但是改變顏色

最壞可能是lgn, 其他可能是多次,或零次。

定義勢能函式phi(t)=sum, 其中如果x是紅色,或者x是黑有兩個紅孩子,則w(x)=0; 如果x是黑,沒有紅孩子,則w(x)=1; 如果x是黑,有兩個紅孩子,則w(x)=2。

證明:任一rb_insert/rb_delete後,phi(t)至少減少一。從任意混合的插入刪除序列的分攤代價是o(1)。

例2 自組織鍊錶:

搜尋必須從煉表頭開始,如果在第k項找到,則代價為k。

搜尋後允許使用任何啟發式方法調整鍊錶順序。

heuristic knowing entire access sequence.雖然我不知道這種最優方法的代價,

但是我們使用勢能分析,即使預先不知道訪問序列,move-to-front heuristic方法的代價不超過最優方法代價的兩倍。

例3 伸展樹[2]

如果想要和紅黑樹一樣的分攤複雜度,而編碼複雜度不要那麼高,就用這個。

參考

[1] 演算法導論第三版

[2] 

SQL資料分攤

場景 到季未公司按照部門貢獻率進行對各部門發放獎金,然後部門內部按效績優先順序分攤獎金 方案 參考網上資料,使用cte函式遞迴處理 if object id tempdb.emplbonus is not null drop table emplbonus create table emplbonu...

分攤 分配 定期重過賬

分攤是既分攤初級成本又分攤次級成本至co中物件的方法。成本分攤的規則可以有很多,比如根據統計指標,根據百分比,根據權重,根據固定金額等等。我們在系統中將分攤規則定義在乙個重要的引數 分攤迴圈中。分攤迴圈是多行的。每一行中都定義了分攤成本流的傳送方,接受方,分攤規則等內容。在月末我們指定需要執行的迴圈...

資料結構 向量的擴充(分攤複雜度分析)

在原本的向量中,由於採用靜態空間管理策略 開闢內部陣列 elem並使用一段連續的物理空間 capacity 總容量 size 當前實際規模 這個管理策略顯然存在不足,會發生上溢或者下溢 1 上溢 overflow elem不足以存放所有元素 2 下溢 underflow elem中元素寥寥無幾 裝填...