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)  編輯  收藏 所屬分類: 算法

          主站蜘蛛池模板: 洛川县| 赫章县| 斗六市| 潜江市| 普洱| 来宾市| 平江县| 淮北市| 米脂县| 汉川市| 正定县| 永修县| 湘潭县| 福海县| 高安市| 恩平市| 台东县| 张北县| 内丘县| 阜新市| 武川县| 图们市| 陆良县| 方城县| 开封县| 龙泉市| 东丰县| 灵寿县| 西昌市| 浠水县| 阜平县| 平塘县| 诏安县| 清水县| 会理县| 东乌| 黎川县| 英吉沙县| 织金县| 江城| 西城区|