算法導論讀書筆記(19)

http://www.cnblogs.com/sungoshawk/p/3802553.html

算法導論讀書筆記(19)

最優二叉搜索樹

最優二叉搜索樹 (optimal binary search tree)問題的形式化定義如下:給定一個由 n 個互異的關鍵字組成的序列 K = < k1 , k2 , … , kn >,且關鍵字有序(有 k1 < k2 < … < kn ),我們要從這些關鍵字中構造一棵二叉查找樹。對每個關鍵字 ki ,一次搜索爲 ki 的概率是 pi 。某些搜索的值可能不在 K 內,因此還有 n + 1 個“虛擬鍵” d0 , d1 , … , dn 代表不在 K 內的值。其中, d0 代表所有小於 k1 的值, dn 代表所有大於 kn 的值,而對於 i = 1, 2, …, n - 1 ,虛擬鍵 di 代表所有位於 ki 和 ki+1 之間的值。對每個虛擬鍵 di ,一次搜索對應於 di 的概率是 qi 。下圖是 n = 5個關鍵字的集合上的兩棵二叉查找樹。

其中各結點的概率如下表所示:

每個關鍵字 ki 是一個內部結點,每個虛擬鍵 di 是一個葉子。每次搜索要麼成功(找到某個關鍵字 ki ),要麼失敗(找到某個虛擬鍵 di ),因此有如下公式:

因爲已知了每個關鍵字和每個虛擬鍵被搜索的概率,因而可以確定在一棵給定的二叉查找樹 T 內一次搜索的期望代價。假設一次搜索的實際代價爲檢查的結點個數,即在 T 內搜索所發現的結點的深度加1.所有在 T 內一次搜索的期望代價爲

其中 depthT 代表樹 T 內一個結點的深度。

對給定的一組概率,我們的目標是構造一個期望搜索代價最小的二叉查找樹。把這種樹稱爲最優二叉查找樹。下面將使用動態規劃方法來解決這個問題。

步驟1:一棵最優二叉查找樹的結構

爲描述一棵最優二叉查找樹的最優子結構,首先要看它的子樹。一棵二叉查找樹的任意一棵子樹必定包含在連續範圍內的關鍵字 ki ,…, kj ,有 1 <= i <=j <= n 。另外,一棵含有關鍵字 ki ,…, kj 的子樹必定也含有虛擬鍵 di-1 ,…, dj 作爲葉子。

現在我們可以描述最優子結構:如果一棵最優二叉查找樹 T 有一棵包含關鍵字 ki ,…, kj 的子樹 T’ ,那麼這棵子樹 T‘ 對於關鍵字 ki ,…, kj 和虛擬鍵di-1 ,…, dj 的子問題也必定是最優的。

使用最優子結構來說明可以根據子問題的最優解,來構造原問題的一個最優解。給定關鍵字 ki ,…, kj ,假設 kr ( i <= r <= j ),將是包含這些鍵的一棵最優子樹的根。根 kr 的左子樹包含關鍵字 ki ,…, kr-1 (和虛擬鍵 di-1 ,…, dr-1 ),右子樹包含關鍵字 kr+1 ,…, kj (和虛擬鍵 dr ,…, dj )。我們只要檢查所有的候選根 kr ,並且確定所有包含關鍵字 ki ,…, kr-1 和 kr+1 ,…, kj 的最優二叉查找樹,就可以保證找到一棵最優的二叉查找樹。

步驟2:一個遞歸解

現在可以遞歸地定義一個最優解的值了。選取子問題域爲找一個包含關鍵字 ki ,…, kj 的最優二叉查找樹,其中 i >= 1 , j <= n 且 j >= i - 1。(當 j >= i - 1時沒有真是的關鍵字,只有虛擬鍵 di-1 )。定義 e [ i , j ]爲搜索一棵包含關鍵字 ki ,…, kj 的最優二叉查找樹的期望代價。最終,我們要計算的是 e [ 1 ,n ]。

當 j = i - 1時出現簡單情況。此時只有虛擬鍵 di-1 。期望的搜索代價爲 e [ i , i - 1 ] = qi - 1。

當 j >= i 時,需要從 ki ,…, kj 中選擇一個根 kr ,然後用關鍵字 ki ,…, kr-1 來構造一棵最優二叉查找樹作爲其左子樹,並用關鍵字 kr+1 ,…, kj 來構造一棵最優二叉查找樹作爲其右子樹。當一棵樹成爲一個結點的子樹時,子樹中每個結點的深度增加1。這個子樹的期望搜索代價增加爲子樹中所有概率的總和。對一棵有關鍵字 ki ,…, kj 的子樹,定義概率的總和爲

因此,如果 kr 是一棵包含關鍵字 ki ,…, kj 的最優子樹的根,則有

e [ i , j ] = pr + ( e [ i , r - 1 ] + w ( i , r - 1 )) + ( e [ r + 1 , j ] + w ( r + 1 , j ))

注意

w ( i , j ) = w ( i , r - 1 ) + pr + w ( r + 1 , j )

可以將 e [ i , j ]重寫爲

e [ i , j ] = e [ i , r - 1 ] + e [ r + 1 , j ] + w ( i , j )

假設我們知道該採用哪一個結點 kr 作爲根。我們選擇有最低期望搜索代價的結點作爲根,從而得到最終的遞歸式:


步驟3:計算一棵最優二叉查找樹的期望搜索代價

下面的僞碼以概率 p1 ,…, pn 和 q1 ,…, qn 以及規模爲 n 爲輸入,返回表 e 和 root 。

OPTIMAL-BST(p, q, n)
1  let e[1 .. n + 1, 0 .. n], w[1 .. n + 1, 0 .. n] and root[1 .. n, 1 .. n] be new tables
2  for i = 1 to n + 1
3      e[i, i - 1] = q_i - 1
4      w[i, i - 1] = q_i - 1
5  for l = 1 to n
6      for i = 1 to n - l + 1
7          j = i + l - 1
8          e[i, j] = ∞
9          w[i, j] = w[i, j - 1] + p_j + q_j
10         for r = i to j
11             t = e[i, r - 1] + e[r + 1, j] + w[i, j]
12             if t < e[i, j]
13                 e[i, j] = t
14                 root[i, j] = r
15 return e and root

此過程的操作比較直觀。第1~4行初始化 e [ i , j - 1 ]和 w [ i , j - 1 ]的值。第5~14行的 for 循環利用上面兩個遞歸式來計算 e [ i , j ]和 w [ i , j ],在第10~14行,嘗試每個下標 r 以確定使用哪個關鍵字 kr 來作爲包含關鍵字 ki ,…, kj 的最優二叉查找樹的根。無論何時發現一個更好的關鍵字來作爲根,這個for 循環在 root [ i , j ]中保存下標 r 的當前值。

下圖是根據上面二叉查找樹的關鍵字分佈,程序 OPTIMAL-BST 計算出的表 e [ i , j ]和 w [ i , j ]和 root [ i , j ]。

OPTIMAL-BST 過程需要 Θ ( n3 )。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章