Skip to content

Commit d42c764

Browse files
committed
Merge branch 'stock-example' of github.com:leclere/StochDynamicProgramming.jl into stock-example
2 parents 6d056c8 + 9cf6b26 commit d42c764

File tree

4 files changed

+38
-31
lines changed

4 files changed

+38
-31
lines changed

examples/stock-example.jl

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@
66
# Compare different ways of solving a stock problem :
77
# Min E [\sum_{t=1}^TF c_t u_t]
88
# s.t. s_{t+1} = s_t + u_t - xi_t, s_0 given
9-
# 0 <= s_t <= 1
9+
# 0 <= s_t <= 1
1010
# u_min <= u_t <= u_max
11-
# u_t choosen knowing xi_1 .. xi_t
11+
# u_t choosen knowing xi_1 .. xi_t
1212
#############################################################################
1313

1414
push!(LOAD_PATH, "../src")
1515
using StochDynamicProgramming, JuMP, Clp, Distributions
1616

1717
######## Optimization parameters ########
18-
# choose the LP solver used.
18+
# choose the LP solver used.
1919
const SOLVER = ClpSolver()
2020
# const SOLVER = CplexSolver(CPX_PARAM_SIMDISPLAY=0)
2121
# const SOLVER = GurobiSolver()
@@ -33,7 +33,7 @@ const CONTROL_MIN = 0
3333
const XI_MAX = 0.3
3434
const XI_MIN = 0
3535
const N_XI = 10
36-
36+
# initial stock
3737
const S0 = 0.5
3838

3939
# create law of noises
@@ -67,7 +67,7 @@ spmodel = LinearDynamicLinearCostSPmodel(N_STAGES,
6767
xi_laws)
6868

6969
set_state_bounds(spmodel, s_bounds)
70-
paramSDDP = SDDPparameters(SOLVER, 10, 0, MAX_ITER) # 10 forward path, stop at MAX_ITER
70+
paramSDDP = SDDPparameters(SOLVER, 10, 0, MAX_ITER) # 10 forward path, stop at MAX_ITER
7171

7272
######### Solving the problem via SDDP
7373
V, pbs = solve_SDDP(spmodel, paramSDDP, 10) # display information every 10 iterations
@@ -76,17 +76,17 @@ println("Lower bound obtained by SDDP: "*string(lb_sddp))
7676

7777
######### Solving the problem via Dynamic Programming
7878

79-
stateSteps = [0.1]
80-
controlSteps = [0.1]
79+
stateSteps = [0.01]
80+
controlSteps = [0.01]
8181
infoStruct = "HD" # noise at time t is known before taking the decision at time t
8282

8383
paramSDP = SDPparameters(spmodel, stateSteps, controlSteps, infoStruct)
84-
V = sdp_optimize(spmodel,paramSDP)
85-
lb_sdp = StochDynamicProgramming.get_value(spmodel,paramSDP,V)
84+
Vs = sdp_optimize(spmodel,paramSDP)
85+
lb_sdp = StochDynamicProgramming.get_value(spmodel,paramSDP,Vs)
8686
println("Lower bound obtained by SDP: "*string(lb_sdp))
8787

8888

8989
######### Comparing the solution
90-
#scenarios = StochDynamicProgramming.generate_scenarios(xi_laws,1)
90+
#scenarios = StochDynamicProgramming.generate_scenarios(xi_laws,1)
9191
#costs, stocks = forward_simulations(spmodel, params, V, pbs, scenarios)
9292

src/SDDPoptimize.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ function run_SDDP(model::SPModel,
124124
if (display > 0) && (iteration_count%display==0)
125125
println("Pass number ", iteration_count,
126126
"\tLower-bound: ", round(get_bellman_value(model, param, 1, V[1], model.initialState),4),
127-
"\tTime: ", round(toq(),2))
127+
"\tTime: ", round(toq(),2),"s")
128128
end
129129

130130
end

src/SDPoptimize.jl

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -140,34 +140,41 @@ Returns :
140140
function sdp_optimize(model::SPModel,
141141
param::SDPparameters,
142142
display=true::Bool)
143-
144-
function true_fun(x...)
143+
144+
function true_fun(t,x,u,w)
145145
return true
146146
end
147-
function zero_fun(x...)
147+
function zero_fun(x)
148148
return 0
149149
end
150-
150+
151151
if isa(model,PiecewiseLinearCostSPmodel)||isa(model,LinearDynamicLinearCostSPmodel)
152+
function cons_fun(t,x,u,w)
153+
test = true
154+
for i in 1:model.dimStates
155+
test &= (x[i]>=model.xlim[i][1])&(x[i]<=model.xlim[i][2])
156+
end
157+
return test
158+
end
152159
if in(:finalCostFunction,fieldnames(model))
153-
SDPmodel = StochDynProgModel(model, model.finalCostFunction, true_fun)
160+
SDPmodel = StochDynProgModel(model, model.finalCostFunction, cons_fun)
154161
else
155-
SDPmodel = StochDynProgModel(model, zero_fun, true_fun)
162+
SDPmodel = StochDynProgModel(model, zero_fun, cons_fun)
156163
end
157164
elseif isa(model,StochDynProgModel)
158165
SDPmodel = model
159166
else
160-
error("cannot build StochDynProgModel from current SPmodel. You need to implement
167+
error("cannot build StochDynProgModel from current SPmodel. You need to implement
161168
a new StochDynProgModel constructor.")
162169
end
163-
170+
164171
#Display start of the algorithm in DH and HD cases
165172
if (param.infoStructure == "DH")
166173
V = sdp_solve_DH(SDPmodel, param, display)
167174
elseif (param.infoStructure == "HD")
168175
V = sdp_solve_HD(SDPmodel, param, display)
169176
else
170-
error("param.infoStructure is neither 'DH' nor 'HD'")
177+
error("param.infoStructure is neither 'DH' nor 'HD'")
171178
end
172179

173180
return V
@@ -198,7 +205,7 @@ Returns :
198205
function sdp_solve_DH(model::StochDynProgModel,
199206
param::SDPparameters,
200207
display=true::Bool)
201-
208+
202209
TF = model.stageNumber
203210
next_state = zeros(Float64, model.dimStates)
204211
law = model.noises
@@ -264,10 +271,10 @@ function sdp_solve_DH(model::StochDynProgModel,
264271
w_sample = samples[:, w]
265272
proba = probas[w]
266273
next_state = model.dynamics(t, x, u, w_sample)
267-
268-
274+
275+
269276
if model.constraints(t, next_state, u, w_sample)
270-
277+
271278
count_admissible_w = count_admissible_w + proba
272279
ind_next_state = real_index_from_variable(next_state, x_bounds, x_steps)
273280
next_V = Vitp[ind_next_state...]
@@ -383,7 +390,7 @@ function sdp_solve_HD(model::StochDynProgModel,
383390
#Compute expectation
384391
for w in 1:sampling_size
385392
admissible_u_w_count = 0
386-
best_V_x_w = 0.
393+
best_V_x_w = Inf
387394
next_V_x_w = Inf
388395
w_sample = samples[:, w]
389396
proba = probas[w]
@@ -410,7 +417,6 @@ function sdp_solve_HD(model::StochDynProgModel,
410417
expected_V += proba*best_V_x_w
411418
count_admissible_w += (admissible_u_w_count>0)*proba
412419
end
413-
414420
if (count_admissible_w>0.)
415421
expected_V = expected_V / count_admissible_w
416422
end
@@ -438,8 +444,9 @@ Returns :
438444
- V(x0) (Float64)
439445
"""
440446
function get_value(model::SPModel,param::SDPparameters,V::Array{Float64})
441-
ind_x0 = index_from_variable(model.initialState, model.xlim, param.stateSteps)
442-
return V[ind_x0...,1]
447+
ind_x0 = real_index_from_variable(model.initialState, model.xlim, param.stateSteps)
448+
Vi = value_function_interpolation(model, V, 1)
449+
return Vi[ind_x0...,1]
443450
end
444451

445452

src/objects.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ type LinearDynamicLinearCostSPmodel <: SPModel
3737
for i = 1:dimStates
3838
push!(xbounds, (-Inf, Inf))
3939
end
40-
40+
4141
return new(nstage, dimControls, dimStates, dimNoises, xbounds, ubounds, x0, cost, dynamic, aleas)
4242
end
4343
end
@@ -103,7 +103,7 @@ type StochDynProgModel <: SPModel
103103
noises::Vector{NoiseLaw}
104104

105105
function StochDynProgModel(model::LinearDynamicLinearCostSPmodel, final, cons)
106-
return new(model.stageNumber-1, model.dimControls, model.dimStates,
106+
return new(model.stageNumber, model.dimControls, model.dimStates,
107107
model.dimNoises, model.xlim, model.ulim, model.initialState,
108108
model.costFunctions, final, model.dynamics, cons,
109109
model.noises)
@@ -122,7 +122,7 @@ type StochDynProgModel <: SPModel
122122
return saved_cost
123123
end
124124

125-
return new(model.stageNumber-1, model.dimControls, model.dimStates,
125+
return new(model.stageNumber, model.dimControls, model.dimStates,
126126
model.dimNoises, model.xlim, model.ulim, model.initialState,
127127
cost, final, model.dynamics, cons,
128128
model.noises)

0 commit comments

Comments
 (0)