Change Dir

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

          統計

          留言簿(18)

          積分與排名

          “牛”們的博客

          各個公司技術

          我的鏈接

          淘寶技術

          閱讀排行榜

          評論排行榜

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

          不知不覺已經寫到第10個問題了,動態規劃的問題相信大家也發現了一些規律,看到什么樣的問題知道動態規劃求解呢?基本上所有的問題都類似最短路,定義了一個狀態后根據狀態列動態規劃方程,方程的形式一般是遞歸式,包含一個子結構的更新過程……接下來就是羅列問題了:第10題是算導中提過的題目,DEADLINE調度問題(其實這個問題還有一個高階版本)。

          deadline問題的描述是:一臺處理器可以處理n個作業,表示為a1,a2,…,an。每個作業aj有相等的運行時長(如果不等也作為變量呢?),有效益pj以及截止時間dj。機器是串行的,也就是說一個時刻只能處理一個作業。而且作業是原子的,不可拆分。獲得效益pj的前提是aj一定要在dj之前完成。請給出一個算法來達到最優調度,即效益最大化。之前講到,在看到最優化問題時就直接想DP求解,這個當然是個好習慣,但是這里再介紹一個思路就是優先可以先考慮貪心是否可解,相對列動態規劃方程定義狀態這些事情,貪心往往更直觀更簡單(人心不足啊)。

          這個問題是可以使用貪心法求解的,貪心算法不是我們這個系列問題的關鍵,但是也可以簡單談一下貪心:貪心的核心是要確定正確的貪心目標,就是在一系列決策做出時,每個步驟選擇的理由是什么,比如這個問題,是按照處理時間排序后貪心?還是按照效益排序后貪心?根據目標是效益最大化,那么就可以做出正確選擇了。

          當然動態規劃比貪心優勢的一點就是貪心是個局部策略,不是所有問題都能得到全局最優解,而DP是全局最優的,使用DP總能得到最優決策。針對本題,我們思考如何定義一個狀態來列出狀態轉移方程。就像考慮其他類似組合優化問題時,看到有決策性步驟問題時,我們定義狀態是帶有步驟標號的,也就是第一章提到的stage decision,每個stage用k表示,到了第i個stage后,剩余的可決策集S作為另一個狀態元素,于是我們定義狀態(k,S),其中k是stage,S是表示當前狀態下剩余可選決策。為了保證S集是可選擇的決策集,我們需要對deadline排序,即按照截止時間排序。這樣,我們列DPFE如下:f(k,S)=max d∈S{c(d|s)+f(k+1,S-wmqeeuq)},其中c(d|s)=pd,基本條件是f(k,S)=0,當k=1+N或者S為空時。

          以具體數據為例:5個作業標號為{0,1,2,3,4},其中每個作業的效益為{10,15,20,1,5},完成deadline為{1,2,2,3,3},求最優策略的效益。可以看到按照之前貪心解法,按照效益排序后,為20,15,10,5,1,而對應的截止時間也變為2,2,1,3,3,這樣最優解就是20+15+5=40。DP的解法如下源碼:

             1: package com.jybat.dp;
             2:  
             3: import java.util.Set;
             4: import java.util.SortedSet;
             5: import java.util.TreeSet;
             6:  
             7: //deadline scheduling of unit-time jobs
             8: public class DEADLINE {
             9:  
            10:     private static int[] profit = { 10, 15, 20, 1, 5 };
            11:     private static int[] deadline = { 1, 2, 2, 3, 3 }; // sorted
            12:     private static int N = profit.length; // no.of jobs
            13:  
            14:     private static SortedSet<Integer> setOfAllJobs = new TreeSet<Integer>();
            15:  
            16:     public DEADLINE() {
            17:         for (int i = 0; i < N; i++) {
            18:             setOfAllJobs.add(i);
            19:         }
            20:     }
            21:  
            22:     private static boolean feasible(SortedSet<Integer> jobs, int k, int d) {
            23:         int j = 0;
            24:         for (int i = 0; i < N; i++) {
            25:             if (!(jobs.contains(new Integer(i))) || i == d) {
            26:                 // if i already chosen or next (and is j-th),
            27:                 // does it meet its deadline?
            28:                 if (deadline[i] < ++j) {
            29:                     return false;
            30:                 }
            31:             }
            32:         }
            33:         return true;
            34:     }
            35:  
            36:     private static int cost(SortedSet<Integer> jobs, int k, int d) {
            37:         if (feasible(jobs, k, d)) {
            38:             return profit[d];
            39:         } else {
            40:             return 0;
            41:         }
            42:     }
            43:  
            44:     // jobs not yet chosen at stage k
            45:     public int f(SortedSet<Integer> jobs, int k) {
            46:         if (k > N)
            47:             return 0;
            48:         int max = Integer.MIN_VALUE;
            49:         for (int d : jobs) {
            50:             SortedSet<Integer> nJobs = copySet(jobs);
            51:             nJobs.remove(d);
            52:             int t = cost(jobs, k, d) + f(nJobs, k + 1);
            53:             if (t > max)
            54:                 max = t;
            55:         }
            56:         return max;
            57:     }
            58:  
            59:     private SortedSet<Integer> copySet(SortedSet<Integer> jobs) {
            60:         SortedSet<Integer> nJobs = new TreeSet<Integer>();
            61:         for (int i : jobs) {
            62:             nJobs.add(i);
            63:         }
            64:         return nJobs;
            65:     }
            66:  
            67:     /**
            68:      * @param args
            69:      */
            70:     public static void main(String[] args) {
            71:         DEADLINE d = new DEADLINE();
            72:         System.out.println(d.f(setOfAllJobs, 1));
            73:     }
            74:  
            75: }

          posted on 2014-05-12 16:54 changedi 閱讀(2652) 評論(1)  編輯  收藏 所屬分類: 算法

          評論

          # re: 深入理解動態規劃的一系列問題(10) 2014-05-12 23:45 ME娛樂澳門銀座時時彩平臺

          贊一個  回復  更多評論   

          主站蜘蛛池模板: 莒南县| 邻水| 石渠县| 吉林市| 五峰| 民县| 城口县| 大荔县| 北安市| 登封市| 平果县| 重庆市| 陕西省| 峨边| 山东| 城市| 罗甸县| 钦州市| 虞城县| 长泰县| 武邑县| 科技| 松潘县| 抚远县| 新河县| 孟村| 龙山县| 潜山县| 米脂县| 微山县| 韩城市| 东平县| 安多县| 泰来县| 甘泉县| 庆阳市| 吴桥县| 安吉县| 垦利县| 新丰县| 始兴县|