動態規划實例(四)最優二叉搜索樹(Optimal Binary Search Tree)


問題

最優二叉搜索樹(Optimal Binary Search Tree,Optimal BST)問題,形式化定義:給定一個n個不同關鍵字的已排序的序列K=<k1, k2, ..., kn>(k1<k2<...<kn),用這些關鍵字構造一棵二叉搜索樹 —— 對每個關鍵字ki,都有一個概率pi表示其搜索頻率。對於不在K中的搜索值構造n+1個”偽關鍵字“d0, d1, d2, ..., dn —— 偽關鍵字di表示所有在ki和ki+1之間的值(i=1,2,...,n-1,d0表示所有小於k1的值,dn表示所有大於kn的值),每個偽關鍵字di對應一個概率qi(搜索頻率)。 

例如,對一個n=5的關鍵字集合及如下的搜索頻率,構造二叉搜索樹。逐點計算的期望搜索耗費(contribution = (depth + 1) * probability)如右下表,從表中得到k5的搜索概率最高,根節點是k2

二叉樹搜索樹的期望耗費:

思路

  • 步驟1:最優二叉搜索樹的結構,如果一顆最優二叉搜索樹T有一顆包含關鍵字ki, ..., kj的子樹T',那么T'必然是包含ki, ..., kj和偽關鍵字di-1, ..., dj的子問題最優解。
  • 步驟2:一個遞歸式,定義w(i, j)是包含關鍵字ki, ..., kj的子樹所有概率之和,e[i, j]為期望耗費,則...

 

 

  • 步驟3:計算最優二叉搜索樹的期望代價。

實現

def optimal_bst(p,q,n):
    e=[[0 for j in range(n+1)]for i in range(n+2)]
    w=[[0 for j in range(n+1)]for i in range(n+2)]
    root=[[0 for j in range(n+1)]for i in range(n+1)]
    for i in range(n+2):
        e[i][i-1]=q[i-1]
        w[i][i-1]=q[i-1]
    for l in range(1,n+1):
        for i in range(1,n-l+2):
            j=i+l-1
            e[i][j]=float("inf")
            w[i][j]=w[i][j-1]+p[j]+q[j]
            for r in range(i,j+1):
                t=e[i][r-1]+e[r+1][j]+w[i][j]
                if t<e[i][j]:
                    e[i][j]=t
                    root[i][j]=r
    return e,root
 
if __name__=="__main__":
    p=[0,0.15,0.1,0.05,0.1,0.2]
    q=[0.05,0.1,0.05,0.05,0.05,0.1]
    e,root=optimal_bst(p,q,5)
    for i in range(5+2):
        for j in range(5+1):
            print(e[i][j]," ",end='')
        print()
    for i in range(5+1):
        for j in range(5+1):
            print(root[i][j]," ",end='')
        print() 
    

時間復雜度:T(n)=O(n3)
空間復雜度:S(n)=O(n2)

代碼引自:算法導論程序39--最優二叉搜索樹(Python)_夜空霓虹的博客-CSDN博客_最優二叉搜索樹python


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM