Try   HackMD

Merge sort 論文閱讀與見解

Introduction

閱讀 commit b5c56e0 提及之三篇論文並思考 merge sort 與其變形之優劣勢,並嘗試提示洞見與可能的改進。該 commit 提及的論文分別如下

  • Bottom-up Mergesort: A Detailed Analysis
  • The cost distribution of queue-mergesort, optimal mergesorts, and power-of-two rules
  • Queue-Mergesort

Bottom-up Mergesort

C(N) 表示排序
N
個元素最少需要做幾次比較,這項指標對排序演算法的效能影響最大。 Divide-and-conquer 演算法幾乎都存在週期性現象, merge sort 也不例外。該論文首先定義
Cb,td(N),Cw,td(N),Ca,td(N)
這三個參數表示 top-down mergesort 在 best case, worst case 與 average case 所需要的比較次數。
Cw,td(N)
還可以因為其週期性性質而歸納出以下公式
Cw,td(N)=Nlg(N)+NA(lg(N))+1

其中
A(x)=1{x}21{x}
,因此上式展開後可得
Cw,td(N)=Nlg(N)+N(1lg(N)21lg(N))+1

不過我不理解此處為何能清楚展現 mergesort 的週期特性,同時對於 best case 來說
Cb,td(N)=n<Nv(n)

v(n)
即是
n
的 population count ,這篇論文主要是想要推導出對於 bottom-up mergesort 的 closed form 公式,也就是
Cb,bu(N),Cw,bu(N),Ca,bu(N)

Bottom-up mergesort 和 top-down mergesort 差別在於 splitting 的方法, bottom-up mergsort 採用的是 "power-of-two" splitting ,而 top-down mergesort 則是採用 "half-and-half" splitting ,這也造成呼叫合併的次數會不同,把 mergesort 視覺化可以發現 merging process 看起來像一棵樹,而 bottom-up mergesort 在第

j 層 ( 0-index ,最底層是 0 ) 有
N2j+1
個進行完整合併的節點,也就是將
2j
個元素與
2j
個元素進行合併,另外若
N  mod  2j+1>2j
則會多一個 incomplete merge 來合併
2j
個元素與
N  mod  2j
個元素,總結來說對於
N
個元素的 bottom-up mergesort 總共需要
i=0kN2i
個 complete merge 與
popcount(N)1
個 incomplete merge 。假設合併
(n,m)
元素所需的比較次數表示為
cn,m

min{n,m}cn,mn+m1

並且
cn,m=j
的機率為
(j1n1)+(j1m1)(n+mn)

因此
cn,m
的期望值為
E{cn,mr}=nm(1n+r+1m+r)[n+m+1]r1

其中
[x]k=x(x+1)(x+k1)

首先推導 best case 也就是

Cb,bu(N) , best cases 發生在每個合併過程都是最佳也就是
cn,m=min{n,m}
時,因此對於 complete merge 來說總比較次數是
j=0k1(2jN2j+1)
,因為 complete merge 在第
j
層進行
N2j+1
(2j,2j)
的合併,
k=lg(N)
。然後進行
j=1kbj(bj1b1b0)2
次 incomplete merge ,總共會是
Cb,bu(N)=n<Nv(n)

同時根據 Trollope-Delange formula 可以得出
n<Nv(n)=12Nlg(N)+NF0(lg(N))

因此可以推導出以下 (看不出如何推導的)
F0(x)=12xj0(βj12)(00βj+1βj+2)2x2=fke2πikx

F0(x)
做圖可看出他的週期特性。

worst case 則是每次

(n,m)合併都使用到
(n+m1)
次比較,可以推得
Cw,bu(N)

Nlg(N)+N[1N0<jk(bj1)(bj1bj2b0){lg(N)}2v2(N)N]+1

其中
v2(N)
為 trailing zeros ,其中 linear term 是
1N0<jk(bj1)(bj1bj2b0){lg(N)}2v2(N)N
做圖後也可看出他的週期特性。
Average case 則是透過加總每個合併的比較次數期望值,同樣可以在 linear term 發現週期特性。

Bottom-up mergesort v.s. Top-down mergesort

兩者在 best case 當中比較次數會相同,但 worst case 和 average case 皆是 top-down mergesort 比較次數更少,並且可以證明 top-down mergesort 的 splitting strategy 使得它在 worst case 和 average case 上都表現得比其他 mergesort 變形更好。只有當

N 為二的指數時, 兩種演算法在 worst case 上的表現才會相同。

Queue-mergesort

建構一個 queue 並且當中的元素都是排序好的鍵結串列,一開始每個節點都是一個串列, queue-mergesort 的演算法如下

while (Q.size > 1) {
    Q.put(Merge(Q.get, Q.get))
}

每次把 queue head 的前兩個元素取出並進行合併,把合併後的鍵結串列放入 queue tail ,不斷進行直到 queue 當中只有一個元素也就是剩一個鍵結串列。特別注意到在任何時間點, queue 當中鍵結串列的長度都是單調遞增的。
此論文嘗試證明 queue-mergesort 是 optimal mergesort ,而 optimal mergesort 的定義代表在排序任何數量

n 個元素的情況下,該 mergesort 在 worst case 下的比較次數是最少,就代表該 mergesort 是 optimal mergesort 。
任何 mergesort 的過程都可以畫成一顆樹狀結構圖, top-down mergesort 每次把
n
個元素拆成兩個集合大小分別是
n2
n2
, bottom-up mergesort 則是把每個元素當成單一鍵結串列來看待並兩兩合併,每個 leaf node 的權重是 1 代表只有一個元素,每個 internal node
v
的權重是
w(v)
同時也代表該節點代表的鍵結串列的元素數量,我們知道進行
(m,n)
的合併 worst case 需要
m+n1
次比較,因此對於 internal node
v
來說 worst case 需要
w(v)1
次比較,把整顆二元樹的內部節點權重加總即是該 mergesort 在 worst case 的比較次數總數
vT[w(v)1]=[vTw(v)](n1)

同時定義整棵樹的權重
w(T)=w(v)
,因此可以定義 optimal mergesort 代表
w(T)w(T)

如何證明 queue mergesort 是 optimal mergesort 呢?我們需要了解兩種特性

  • w(T)=E(T)
    ,其中
    E(T)
    代表樹
    T
    的 external path length ,假設
    l
    代表樹
    T
    的 leaf node ,則
    h(l)
    代表 root 和
    l
    的距離也就是邊數,因此
    E(T)=lh(l)
    ,而我們又知道
    w(T)=E(T)
    ,所以證明 optimal mergesort 可以轉化為找到 mergesort 的樹
    T
    滿足
    E(T)E(T)
  • Huffman encoding
    此演算法可以建構出 weighted external path length 最小的 binary tree ,透過將 leaf node 透過他們的權重排序
    w1,w2,,wn
    後每次將最小的兩個節點拿出來合併,合併後的節點權重是
    wi+wj
    然後再插入回節點集合當中,不斷重複直到剩下一個元素。

不難看出 queue mergesort 就是所有 leaf node 權重皆為一的 Huffman encoding ,因此 queue mergesort 可以建構出一顆有最小 external path length 的 binary tree ,也證明了 queue mergesort 是 optimal mergesort 。

Cost Distribution of Queue-Mergesort, Optimal Mergesorts, and power-of-2 Rules

不同版本 Merge Sort 的比較次數可以利用以下遞迴式來表達

fn=fτ(n)+fnτ(n)+gn
其中
gn
代表合併的成本,並且
τ(n)
隨著不同的實作有不同的可能

  • τ(n)=n2
    , top-down mergesort 版本
  • τ(n)=2log2(n2)
    , bottom-up mergesort ( max power-of-2 rule )
  • τ(n)=2log2(2n3)
    , queue-mergesort ( balanced power-of-2 rule )

特別注意在 balanced power-of-2 rule 當中只有選擇

2log2(2n3) 是平衡的,它是一個介於
n/3
2n/3
之間的二的冪次方數。雖然 Queue Mergesort 剛好符合 Heap recurrence 也就是
fn=min1jn(fj+fnj)+gn
的解,並且實作上不需要事先知道要排序的 input size ,非常適合用在鍵結串列上,但我們付出的代價是它並非 stable sort 。

以下分析中會使用的符號如下

  • ρ=min(2log2(2n3),n2log2(2n3))
  • λ=nρ

Lemma 1. The cost of QM is described by the heap recurrence

fn=fλ+fρ+gn

證明方法和 Huffman code 過程一樣,設定在第 i 次迴圈時 queue 當中元素大小為

ai,iai,i+1ai,i+2,,ai,n ,一開始
a1,j=1,j
,最後
an,n=n

每個迴圈過程
(ai,i,,ai,n)
會轉變為
(ai+1,i+1,,ai+1,n)
,並且
ai+1,j=ai,j+1
ai+1,n=ai,i+ai,i+1
,並保有以下 loop invariance

  • 存在整數
    k
    使得
    2kai,j2k+1
  • j={i,,n1},12ai,jai,j+11
  • 最多一個
    ai,j
    不是二的冪

Lemma 2. The solution of

fn of the heap recurrence with
f1=g1
is

fn=j=1L(n2j1n2j1)g2j+j=0Lgnj

證明:
原本的 heap recurrence 可以寫為

fn=fnL1+f2L1+gnL+bL2(f2L2+g2L1)+bL1(f2L1+g2L)

透過歸納法可得

fn=j=0L1(1+bj)f2j+j=1Lbj1g2j+j=0Lgnj
最後把
bj=n2j2n2j+1
帶入即可得證。

Lemma 3. Assume that

fn satisfies the heap recurrence. Then
fn/nl<
iff
gn=o(n)
and
j0g2j2j=l

Lemma 4. If

fn satisfies the heap recurrence and
gn=O(1)
, then
fn=j0g2j2jn+O(log(n))

以上兩個定理可以歸納出 power-of-2 rule 的一個優點,假設

gn=O(n/log(n)),n2L
g2L=O(2L/L1+ε)
,則
fn=O(n)
,但如果把這組合併的 cost
gn
套用在 half-half rule 上,則
fn=O(nlog(n)log(n))

如此一來我們可以推論,若合併的時間複雜度是
o(n)
,此時若我們可以把輸入大小
n
擴展到二的冪,則整體時間複雜度可以維持限性。

The analysis of queue-mergesort

假設有兩個排序好的序列,元素數量分別是

x,y ,則合併它們的代價如下

  • Best case :
    min(x,y)
  • Worst case :
    x+y1
  • Average case :
    u(x,y)=x+yxy+1yx+1
  • Variance case :
    v(x,y)=x(2x+y)(y+1)(y+2)+y(2y+x)(x+1)(x+2)(xy+1+yx+1)2

Worst case
假設 Queue mergesort 在 worst case 的總比較次數會是

Wn
W1=0

Wn=Wρ+Wλ+n1
。我們可以推得
Wn=nlog2(n)+nA(log2(n))+1

A(t)
是一個連續的週期性函數,週期為 1
A(t)=1{t}21{t}

平均值是
121log(2)
,並且透過推導可得
Wn=j=1nlog2(j)
,可以推斷若 dividing rule 滿足
n(j,nj),ρjn2
,則它是 worst case optimal 。所以 Top-down Mergesort 和 Queue Mergesort 是 optimal mergesorts 的邊界。

此處看不懂為何這樣的 diving rule 就是 worst case optimal

Best case
假設 Best case 的成本是

Bn ,合併成本
gn
為以下
gn=min(λ,ρ)=ρ={2L1,if  bL1=02L(n2L)=n2L,  if  bL1=1

Bn
則是可推得
Bn={B2n=2Bn+nB2n+1=Bn+Bn+1+n

可得
Bn=j=0nv(j)
,其中
v(j)
代表
j
的二進位表示法的 sum-of-digits ,推得以下。
Bn=12nlog2(n)+nD(log2(n))

Average case
假設 n 個元素的

n! 種排列方式出現的機率完全相同,用
Xn
代表隨機排列下 Queue Mergesort 所需的比較次數

Theorem 1. The average number of comparisons used by QM to sort a random permutation of n elements
滿足

Un=E(Xn)=nlog2(n)+(A(log2(n))α)n+4ϖ(log2(n))+O(1)
其中
α0.26449978
ϖ(u)
O(u),Ω(u)
之間震盪
ϖ(u)=j=0j({2uj}{2uj1})2(1+{2uj}(1{2uj}+2{2uj1}))

Asymptotic Normality

假設

Pn(z)
Xn
的 probability generating function ,則
Pn(z)
滿足
{Pn(z)=Pλ(z)Pρ(z)Qn(z)P1(z)=1

假設
Yn
是 two-way linear merge algorithm for mergin two sorted files of sizes
ρ,λ
,且
Qn(z)
是它的 probability generating function ,則
Qn(z)=E(zYn)=k=1λ(nk1ρ1)+(nk1λ1)(nλ)znk

Theorem 3. The distribution function of the random variable

Xn is asymptotically normal
Fn(x)=Φ(x)+O(log(n)n)

Invariance Principle for power-of-2 recurrence

fn=f2log2(θn)+fn2log2(θn)+gn
其中
12θ<1
,所以
θ=23
並非特別的數字。

Invariance principle
假設

fn 滿足上述遞迴式,且
12θ<1
,則
fnnl<
iff
gn=o(n)
j0g2j2j=l

對於將 floor function 替換成 ceil function ,同樣的結論也適用,而此時

14<θ12

Lemma 8. if

gn=O(1) then the solution to the recurrence satisfies
fn=ln+O(log(n)),where  l=j0g2j2j

Optimal Mergesorts

Average case
我們要找到滿足下列遞迴式並使其最小化的 index

U(n)=min1jn1{U(j)+U(nj)+u(j,nj)}
目標是找到 j 使得
U(n)
最小化,結果會是
j=n2
是最佳解,也就是發生在 top-down mergesort 時。

Variance

V(n)=min1jn1{V(j)+V(nj)+v(j,nj)}
我們可以透過證明
V(n)=βn+O(log(n))
,代表 queue mergesort 的 variance 是 asymptotically minimal 。