Change Dir

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

          統計

          留言簿(18)

          積分與排名

          “牛”們的博客

          各個公司技術

          我的鏈接

          淘寶技術

          閱讀排行榜

          評論排行榜

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

          Optimal Alphabetic Radix-Code Tree Problem(ARC)問題是這樣一個問題,給定一系列節點,每個節點有構建成本,然后構建一棵樹,樹的成本計算方式是這樣的,如果樹的節點是葉子節點,那么它的成本就是它自己,否則如果是非葉節點,那么這棵樹的成本等于所有子樹的和,而ARC問題就是要求個最優樹,使得這棵樹的成本最小化。很顯然看出這個樹的求和是遞歸的。

          這個問題的描述很容易讓我們想起huffman tree,霍夫曼樹是最優二叉樹,滿足的條件就是節點權值*路徑長度,求和后最小。ARC樹與霍夫曼樹類似,也是二叉樹,條件是對所有節點的權值求和后最小,只不過霍夫曼樹因為不遞歸不重疊,所以直接貪心解即可。而ARC樹一個明顯的特點就是遞歸包含。所以我們使用動態規劃來求解。而前提同huffman一樣,需要先對節點權值進行排序。

          問題具體化:有4個節點,分別具有權重(2,3,1,4),現求這四個節點構成的ARC樹。解決這個問題的思路就在于,如果是動態規劃解,那么構建這個樹的方法是如何開始呢?我們知道huffman樹是一個經典的自底向上方法,而ARC動態規劃要轉換為自頂向下。一但思路確定,定義DPFE就很明顯了,我們抽象表示定義S=(w0,w1,…wn),這里的w已經有序,接下來定義狀態(i,j)為{wi,…,wj}的子樹求和,那么動態規劃方程為:f(i,j)=min i≤d<j {c(i,j,d)+f(i,d)+f(d+1,j)} 當i<j。基本條件是f(i,j)=0當i=j時,成本計算函數c(i,j,d)=Σwk k=i,…,j。目標函數是求f(0,n)。我們以中綴括號表示一棵ARC樹,那么對于具體化問題的節點集(2,3,1,4),最后的結果就是(((2,1),3),4)。這棵樹的權值為f(S)=(2+1)+((2+1)+3)+(2+1+3+4)=19。

          代碼如下:

             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.Arrays;
            19:  
            20: public class ARC {
            21:  
            22:     private static double[] weight = { 2, 3, 1, 4 };
            23:  
            24:     private static int N = weight.length - 1;
            25:  
            26:     private static double sum(int p, int q) {
            27:         double result = 0.0;
            28:         for (int k = p; k <= q; k++) {
            29:             result += weight[k];
            30:         }
            31:         return result;
            32:     }
            33:     
            34:     public static double f(int firstIndex, int lastIndex){
            35:         if(firstIndex == lastIndex)
            36:             return 0.0;
            37:         double min = Double.MAX_VALUE;
            38:         for(int d=firstIndex;d<lastIndex;d++){
            39:             double t = f(firstIndex,d) + f(d+1,lastIndex) + sum(firstIndex,lastIndex);
            40:             if(t<min)
            41:                 min = t;
            42:         }
            43:         return min;
            44:     }
            45:  
            46:     /**
            47:      * @param args
            48:      */
            49:     public static void main(String[] args) {
            50:         Arrays.sort(weight);
            51:         System.out.println(f(0,N));
            52:     }
            53:  
            54: }

          posted on 2014-04-16 15:06 changedi 閱讀(1759) 評論(0)  編輯  收藏 所屬分類: 算法

          主站蜘蛛池模板: 隆昌县| 湘西| 丁青县| 日照市| 平谷区| 安西县| 宣恩县| 宣化县| 介休市| 招远市| 连州市| 贡觉县| 攀枝花市| 车险| 霍州市| 河津市| 西城区| 东城区| 营山县| 铜陵市| 永清县| 清新县| 金溪县| 朔州市| 日喀则市| 平顶山市| 兰坪| 顺昌县| 皮山县| 黄石市| 湖口县| 措美县| 中西区| 阳谷县| 聂荣县| 沙田区| 张家川| 奇台县| 麻阳| 汾西县| 通化市|