深入理解動態(tài)規(guī)劃的一系列問題(11)
動態(tài)規(guī)劃本質(zhì)上的問題基本就如之前所述,之前的問題也都比較簡單。復(fù)雜的動態(tài)規(guī)劃問題有幾種表現(xiàn),其中之一就是成本函數(shù)計(jì)算復(fù)雜,狀態(tài)轉(zhuǎn)移過程需要考慮的細(xì)節(jié)比較多。今天講的這個問題就滿足這個條件:DPP問題(Discounted Profits Problem)
問題是這樣的:假設(shè)有一個湖,湖里有一些魚,在第一年有b1條魚,之后在第t年開始有bt條魚。漁民靠捕魚賣魚為生,在第t年賣掉xt條魚的話,可以有r(xt)的收益。當(dāng)然捕獲這些魚也會造成c(xt,bt)的成本。魚群每年會自然繁殖,假定繁殖規(guī)律是固定的,每年以s的比例自然增長。同樣漁民手里的錢存在銀行每年也會有固定利息y。請問從第一年開始到第T年,每年應(yīng)該怎么捕魚才能使利益最大化,不能竭澤而漁,當(dāng)然也不能等著餓死。
乍一看這個描述,目標(biāo)很明確——最大化利益,但是條件N多,在DP求解時,要仔細(xì)考慮清楚狀態(tài)轉(zhuǎn)移方程中核心的優(yōu)化條件。首先我們定義狀態(tài),年份t是個天然的stage維度,那么要知道利益,已知條件有收益函數(shù)、成本函數(shù)、增長比例和固定利息,共同的需求就是魚的數(shù)量b,于是狀態(tài)就是(t,b),因?yàn)閠在1~T之間(這本身也是遞歸收斂條件),所以DPFE方程為分段方程:f(t,b)=0當(dāng)且僅當(dāng)t>T,當(dāng)t≤T時,f(t,b)=max xt∈{0,…,b} {r(xt)-c(xt,b)+1/(1+y) * f(t+1,s(b-xt)} 。具體解釋一下,就是我們算t年b條魚時的利益時,假設(shè)捕xt條魚,那么利益等價于賣魚收益r(xt)減去捕魚成本c(xt,b),再加上明年收益及利息。
看起來蠻復(fù)雜的問題,其實(shí)核心的狀態(tài)定義清楚后,邏輯理清,條件雖然多,但是復(fù)雜度只增加在了目標(biāo)計(jì)算上,這樣的問題對于DP里來說個人認(rèn)為算是不太復(fù)雜的。
實(shí)際例子,我們假設(shè)T=2,y=0.05,s=2,初始b1=10(單位是千條),收益函數(shù)也線性化表示為3xt,成本函數(shù)簡化為2xt,這樣收益我們實(shí)際是在求f(1,10),答案輸出是19.05,其最優(yōu)化決策是x1=0,x2=20,即第一年不捕魚,第二年捕完所有魚~~(這個變態(tài)的決策,有點(diǎn)。。。。。。)
源碼:
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: //Discounted Profits Problem
19: //A discounted DP problem from Winston/Venkataramanan
20: //pp.779--780
21: //Used a reproductionFactor of 2 instead of 1.2 so number of
22: //fish takes on integral values, without the need to use a
23: //round or a floor function.
24: public class DPP {
25: private static int T = 2; // planning horizon T=2 years
26: private static double interestRate = 0.05; // assume 5% interest rate
27: private static int initialFishAmount = 10; // initially 10,000 fish in lake
28: private static int reproductionFactor = 2; // in 1 year 100% more fish
29:
30: private static double revenue(int xt) {
31: // simply assume that the sale price is $3 per fish, no matter what
32: return 3.0 * xt;
33: }
34:
35: private static double cost(int xt, int b) {
36: // simply assume that it costs $2 to catch (and process) a fish, no
37: // matter what
38: return 2.0 * xt;
39: }
40:
41: // t is stage number, each stage represents one year
42: // b is current number of fish in lake (scaled to thousands)
43: public static double f(int t, int b) {
44: if (t == T + 1)// T+1 is outside planning horizon
45: return 0.0;
46: // xt is the number of fish to catch and sell
47: // during year t
48: int xt;
49: double max = Double.MIN_VALUE;
50: for (xt = 0; xt <= b; xt++) {
51: double earn = revenue(xt) - cost(xt, b) + 1 / (1 + interestRate)
52: * f(t + 1, reproductionFactor * (b - xt));
53: if (earn > max)
54: max = earn;
55: }
56: return max;
57: }
58:
59: /**
60: * @param args
61: */
62: public static void main(String[] args) {
63: System.out.println(f(1, initialFishAmount));
64: }
65:
66: }
posted on 2014-05-19 13:57 changedi 閱讀(1855) 評論(0) 編輯 收藏 所屬分類: 算法