最优二叉搜索树(动态规划)

假定有一组英语单词与其法语的翻译,要根据英语单词搜索其法语翻译;有以下两个条件
    1. 单词的出现频率不同
    2. 有些单词没有对应的法语单词,称为伪单词
     在给定单词出现频率的前提下,如果组织一棵二叉搜索树,使得所有搜索操作访问的节点总数最少
    问题形式化
        给定一个序列,有n个关键字组成:K =  {k1, k2, ..., kn},对每个关键字有其对应的搜索频率pi
        另外有些K中的伪关键字,我们将其分为n+1个集合:D = {d0, d1, ..., dn},其中d0表示小于k1的值,dn表示大于kn的值,di表示在ki和ki+1之间的值,对应的也有搜索频率qi
        从而        pi + qj = 1        i = 1, ...n    j = 0, ...n

     数据结构表示为一棵二叉搜索树,有n个内部结点{k1, k2, ..., kn},n+1个叶子结点{q0, q1, ..., qn}
    E[搜索代价] = (depth(ki) + 1) * pi + (depth(dj) + 1) * qj
                        = 1 + depth(ki) * pi + depth(dj) * qj             i = 1, ...n    j = 0, ...n

步骤1:最优二叉搜索树的结构
    如果一棵最优二叉搜索树T有一棵包含关键字ki, ..., kj的子树T',则T'必然是包含关键字ki, ..., kj的最优二叉搜索树
步骤2:递归算法
    定义e[i, j]为在包含关键字ki, ..., kj的最优二叉搜索树中进行一次搜索的期望代价,最终希望计算出e[1, n]
    两种情况
    1. j = i - 1,子树只包含伪关键字di-1,从而e[i, j] = qi-1
    2. j >= i,需要从ki, ..., kj选择一个根节点kr, 构造左右子树
         注意一点:当一棵子树成为一个节点的子树时,期望搜索代价的增加值应该为所有节点概率之和
        w(i, j) = pm + qn        m = i, ...j    n = i-1, ...j
        因为深度加一了,从而假设kr为最优二叉树的根节点
        e[i, j] = pr + (e[i, r-1] +  w(i, r-1)) + (e[r+1, j] + w(r+1, j) = e[i, r-1] + e[r+1, j] + w(i, j)
        因此实际上
        e[i, j] = min [ e[i, r-1] + e[r+1, j] + w(i, j)]    r = i, ...j且i <= j
步骤3:计算
    OPTIMAL-BST(p, q, n)
        let e[1..n+1, 0..n], w[1..n+1, 0..n], and root[1..n, 1..n] be new tables
         // e的第一维从1到n+1,对于只包含伪关键字dn的子树,需要计算并保存e[n+1, n];第二维从0开始,对于只包含伪关键字d0的子树,需要计算并保存e[1, 0]
        // root用来保存包含关键字ki, ..., kj的子树的根
        // w保存中间结构,避免重复计算
        for i=1 to n+1
            e[i, i-1] = qi-1
            w[i, i-1] = qi-1
        for l=1 to n
            for i=1 to n-l+1
                j = i+l-1
                e[i, j] = Inf
                w[i, j] = w[i, j-1] + pj + qj
                for r = i to j
                    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 and root
            

你可能感兴趣的:(算法)