Change Dir

          先知cd——熱愛生活是一切藝術的開始

          統計

          留言簿(18)

          積分與排名

          “牛”們的博客

          各個公司技術

          我的鏈接

          淘寶技術

          閱讀排行榜

          評論排行榜

          深入理解動態規劃的一系列問題(8)

                最優二叉搜索樹問題(Optimal Binary Search Tree Problem (BST))是算導上又一個經典例題,給定一系列數據項X={x0,x1,…,x(n-1)},每項都有一個訪問概率p(xi),目標是構建一棵二叉搜索樹使得訪問每個節點的成本最小,即Σ(p(xi) * level(xi))最小,而level(xi)是指xi項在樹中的深度。因為樹的遞歸特性再加二叉搜索樹的應用廣泛性使得用DP來求解這個最優化問題最合適不過。求解思路還是一樣,目標是要列出DPFE,那么第一步要理解目標并把狀態定義出來,有了狀態和執行步驟,轉移方程自然就OK了。因為面臨的是建樹的問題,所以我們的思路會自然想到,自底向上還是自頂向下?而不失一般性的一個規律是,如果是動態規劃解,多數是自頂向下,而貪心解可以做自底向上。所以我們不妨以數據項集作為狀態,即X為狀態,那么自頂向下的執行步驟將是,首先從X中選擇一個x作為節點,然后再計算去除x后的集合X’作為左右子樹……依次遞歸。于是DPFE方程為:f(X)=min a{f(Xl) + f(Xr) + r(a,X)}, X≠?,f(X)=0, X=?。其中Xl={x屬于X,且x<a}(左子樹),Xr={x屬于X,且x>a}。成本函數r(a,X)=Σp(x) x∈X。看到這個解,其實對于熟悉樹結構的人來說,這是非常直觀和自然的一個推斷結果。

                以具體例子來解讀,一個數據集為{A,B,C,D,E},對應的搜索概率為{0.25,0.05,0.2,0.4,0.1}。那么最優解f(X)=f({A,B,C,D,E})=1.9,樹形為:

          image

          程序源碼:

             1: /*
             2:  * Copyright (C) 2013 changedi
             3:  *
             4:  * Licensed under the Apache License, Version 2.0 (the "License");
             5:  * you may not use this file except in compliance with the License.
             6:  * You may obtain a copy of the License at
             7:  *
             8:  * http://www.apache.org/licenses/LICENSE-2.0
             9:  *
            10:  * Unless required by applicable law or agreed to in writing, software
            11:  * distributed under the License is distributed on an "AS IS" BASIS,
            12:  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            13:  * See the License for the specific language governing permissions and
            14:  * limitations under the License.
            15:  */
            16: package com.jybat.dp;
            17:  
            18: import java.util.SortedSet;
            19: import java.util.TreeSet;
            20:  
            21: public class BST {
            22:  
            23:     private int[] data = { 0, 1, 2, 3, 4 };// assume the n data items are
            24:                                             // the ints {0,1,..,n-1}
            25:                                             // corresponding to strings
            26:                                             // { "A", "B", "C", "D",
            27:                                             // "E"}
            28:     private double[] probability = { 0.25, 0.05, 0.2, 0.4, 0.1 };
            29:  
            30:     private static SortedSet<Integer> setOfAllItems = new TreeSet<Integer>();
            31:  
            32:     public BST() {
            33:         for (int i = 0; i < data.length; i++)
            34:             setOfAllItems.add(data[i]);
            35:     }
            36:  
            37:     private double sumOfProbabilitiesOfItems(SortedSet items) {
            38:         double result = 0.0;
            39:         for (int i = ((Integer) items.first()).intValue(); i <= ((Integer) items
            40:                 .last()).intValue(); i++) {
            41:             result += probability[i];
            42:         }
            43:         return result;
            44:     }
            45:  
            46:     private SortedSet setOfItemsLessThanPivot(SortedSet items, int alpha) {
            47:         // conveniently use method headSet() from SortedSet
            48:         // headSet() DOES NOT include alpha
            49:         return new TreeSet(items.headSet(new Integer(alpha)));
            50:     }
            51:  
            52:     private SortedSet setOfItemsGreaterThanPivot(SortedSet items, int alpha) {
            53:         // conveniently use method tailSet() from SortedSet
            54:         // headSet() DOES include alpha
            55:         SortedSet ss = new TreeSet(items.tailSet(new Integer(alpha)));
            56:         ss.remove(alpha);
            57:         return ss;
            58:     }
            59:  
            60:     public double f(SortedSet<Integer> items) {
            61:         if (items.size() == 0)
            62:             return 0.0;
            63:         double min = Double.MAX_VALUE;
            64:         for (int a : items) {
            65:             double t = sumOfProbabilitiesOfItems(items)
            66:                     + f(setOfItemsLessThanPivot(items, a))
            67:                     + f(setOfItemsGreaterThanPivot(items, a));
            68:             if (t < min)
            69:                 min = t;
            70:         }
            71:         return min;
            72:     }
            73:  
            74:     /**
            75:      * @param args
            76:      */
            77:     public static void main(String[] args) {
            78:         BST bst = new BST();
            79:         System.out.println(bst.f(setOfAllItems));
            80:     }
            81:  
            82: }

          posted on 2014-04-28 16:24 changedi 閱讀(1576) 評論(2)  編輯  收藏 所屬分類: 算法

          評論

          # re: 深入理解動態規劃的一系列問題(8) 2014-05-16 18:16 中山婚紗攝影

          學習了,博主辛苦!  回復  更多評論   

          # re: 深入理解動態規劃的一系列問題(8) 2014-05-16 18:16 中山婚紗攝影

          學習了,博主辛苦!~  回復  更多評論   

          主站蜘蛛池模板: 青州市| 通州市| 汤原县| 天柱县| 垫江县| 闵行区| 沾益县| 阳曲县| 含山县| 道孚县| 阿坝县| 遵化市| 永嘉县| 高唐县| 炎陵县| 会泽县| 永川市| 绥江县| 玉溪市| 延津县| 临沭县| 伊金霍洛旗| 丹阳市| 灯塔市| 盐池县| 天峨县| 分宜县| 阿城市| 朝阳县| 怀集县| 栖霞市| 涟水县| 宁陕县| 阿拉善盟| 隆德县| 油尖旺区| 郧西县| 资阳市| 延川县| 馆陶县| 敖汉旗|