Skip to content

Commit 95cd3d5

Browse files
author
Vincent Leclere
committed
Merge branch 'master' into sdp_Interpolations_dot_jl
Conflicts: REQUIRE examples/onedam.jl
2 parents 0de374b + 78491df commit 95cd3d5

File tree

9 files changed

+499
-53
lines changed

9 files changed

+499
-53
lines changed

examples/dam.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function cost_t(t, x, u, w)
5959
end
6060

6161

62-
"""Solve the problem with a solver, supposing the aleas are known
62+
"""Solve the problem assuming the aleas are known
6363
in advance."""
6464
function solve_determinist_problem()
6565
println(alea_year)

examples/damsvalley.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function cost_t(t, x, u, w)
5959
end
6060

6161

62-
"""Solve the problem with a solver, supposing the aleas are known
62+
"""Solve the problem assuming the aleas are known
6363
in advance."""
6464
function solve_determinist_problem()
6565
m = Model(solver=SOLVER)

examples/onedam.jl

Lines changed: 377 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,377 @@
1+
# Copyright 2015, Vincent Leclere, Francois Pacaud and Henri Gerard
2+
# This Source Code Form is subject to the terms of the Mozilla Public
3+
# License, v. 2.0. If a copy of the MPL was not distributed with this
4+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
5+
#############################################################################
6+
# Compare different ways of solving a stock problem
7+
#############################################################################
8+
9+
push!(LOAD_PATH, "../src")
10+
using StochDynamicProgramming, JuMP, Clp, Distributions
11+
12+
######## Optimization parameters ########
13+
# choose the LP solver used.
14+
const SOLVER = ClpSolver()
15+
# const SOLVER = CplexSolver(CPX_PARAM_SIMDISPLAY=0)
16+
# const SOLVER = GurobiSolver()
17+
18+
# Stopping test parameters
19+
const EPSILON = .05
20+
const MAX_ITER = 20
21+
22+
23+
######## Stochastic problem parameters ########
24+
25+
# Define number of stages and scenarios:
26+
const N_STAGES = 3
27+
const N_SCENARIOS = 10
28+
29+
# Define time horizon:
30+
const TF = N_STAGES-1
31+
32+
# Randomnly generate a cost scenario fixed for the whole problem:
33+
const COST = -rand(N_STAGES)
34+
35+
# Define bounds for states and controls:
36+
const VOLUME_MAX = 50
37+
const VOLUME_MIN = 0
38+
39+
const CONTROL_MAX = 50
40+
const CONTROL_MIN = 0
41+
42+
# Define realistic bounds for aleas:
43+
const W_MAX = 40
44+
const W_MIN = 0
45+
46+
# Randomly generate two deterministic scenarios for rain
47+
alea_year1 =round(Int, (W_MAX-W_MIN)*rand(TF)-W_MIN)
48+
49+
# Define initial states of both dams:
50+
const X0 = [50]
51+
52+
53+
# Define dynamic of the dams:
54+
function dynamic(t, x, u, w)
55+
return [x[1] - u[1] - u[2] + w[1]]
56+
end
57+
58+
function dynamic_HD(t, x, u, w)
59+
return [x[1] - u[1] - u[2] + w[1]]
60+
end
61+
62+
function dynamic_DH(t, x, u, w)
63+
x1=x[1] - u[1] + w[1]
64+
return [min(VOLUME_MAX,max(0,x1))]
65+
end
66+
67+
# Define cost corresponding to each timestep:
68+
function cost_t(t, x, u, w)
69+
return COST[t] * (u[1])
70+
end
71+
72+
function cost_t_HD(t, x, u, w)
73+
return COST[t] * (u[1])
74+
end
75+
76+
function cost_t_DH(t, x, u, w)
77+
x1=x[1] - u[1] + w[1]
78+
return COST[t] * (x[1]+w[1]-min(VOLUME_MAX,max(0,x1)))
79+
end
80+
81+
function finalCostFunction(x)
82+
return 0.
83+
end
84+
85+
function constraints(t, x1, u, w)
86+
87+
Bu = (x1[1]<=VOLUME_MAX)
88+
Bl = (x1[1]>=VOLUME_MIN)
89+
90+
return Bu&Bl
91+
92+
end
93+
94+
95+
"""Solve the optimization problem assuming the aleas are known
96+
in advance."""
97+
function solve_determinist_problem()
98+
m = Model(solver=SOLVER)
99+
100+
101+
@defVar(m, VOLUME_MIN <= x1[1:(TF+1)] <= VOLUME_MAX)
102+
@defVar(m, CONTROL_MIN <= u1[1:TF] <= CONTROL_MAX)
103+
104+
@setObjective(m, Min, sum{COST[i]*(u1[i]), i = 1:TF})
105+
106+
for i in 1:TF
107+
@addConstraint(m, x1[i+1] - x1[i] + u1[i] - alea_year1[i] == 0)
108+
end
109+
110+
@addConstraint(m, x1[1] == X0[1])
111+
112+
status = solve(m)
113+
println(status)
114+
println(getObjectiveValue(m))
115+
return getValue(u1), getValue(x1)
116+
end
117+
118+
119+
"""Build admissible scenarios for water inflow over the time horizon."""
120+
function build_scenarios(n_scenarios::Int64)
121+
scenarios = zeros(n_scenarios, N_STAGES)
122+
123+
for scen in 1:n_scenarios
124+
scenarios[scen, :] = round(Int, (W_MAX-W_MIN)*rand(N_STAGES)+W_MIN)
125+
end
126+
return scenarios
127+
end
128+
129+
130+
"""Build probability distribution at each timestep based on N scenarios.
131+
132+
Return a Vector{NoiseLaw}"""
133+
function generate_probability_laws()
134+
aleas = build_scenarios(N_SCENARIOS)
135+
136+
laws = Vector{NoiseLaw}(N_STAGES)
137+
138+
# uniform probabilities:
139+
proba = 1/N_SCENARIOS*ones(N_SCENARIOS)
140+
141+
for t=1:(N_STAGES)
142+
laws[t] = NoiseLaw(aleas[:, t], proba)
143+
end
144+
145+
return laws
146+
end
147+
148+
149+
"""Instantiate the problem."""
150+
151+
function init_problem_sdp_HD()
152+
153+
x0 = X0
154+
aleas = generate_probability_laws()
155+
156+
x_bounds = [(VOLUME_MIN, VOLUME_MAX)]
157+
u_bounds = [(CONTROL_MIN, CONTROL_MAX), (0, VOLUME_MAX)]
158+
159+
N_CONTROLS = 2
160+
N_STATES = 1
161+
N_NOISES = 1
162+
infoStruct = "HD"
163+
164+
stateSteps = [1]
165+
controlSteps = [1, 1]
166+
stateVariablesSizes = [(VOLUME_MAX-VOLUME_MIN)+1]
167+
controlVariablesSizes = [(CONTROL_MAX-CONTROL_MIN)+1, (VOLUME_MAX)+1]
168+
totalStateSpaceSize = stateVariablesSizes[1]
169+
totalControlSpaceSize = controlVariablesSizes[1]*controlVariablesSizes[2]
170+
monteCarloSize = 10
171+
172+
model = StochDynProgModel(N_STAGES-1,
173+
N_CONTROLS,
174+
N_STATES,
175+
N_NOISES,
176+
x_bounds,
177+
u_bounds,
178+
x0,
179+
cost_t_HD,
180+
finalCostFunction,
181+
dynamic_HD,
182+
constraints,
183+
aleas)
184+
185+
params = SDPparameters(stateSteps, controlSteps, totalStateSpaceSize,
186+
totalControlSpaceSize, stateVariablesSizes,
187+
controlVariablesSizes, monteCarloSize, infoStruct)
188+
189+
return model, params
190+
end
191+
192+
193+
function init_problem_sdp_DH()
194+
195+
x0 = X0
196+
aleas = generate_probability_laws()
197+
198+
x_bounds = [(VOLUME_MIN, VOLUME_MAX)]
199+
u_bounds = [(CONTROL_MIN, CONTROL_MAX)]
200+
201+
N_CONTROLS = 1
202+
N_STATES = 1
203+
N_NOISES = 1
204+
infoStruct = "DH"
205+
206+
stateSteps = [1]
207+
controlSteps = [1]
208+
stateVariablesSizes = [(VOLUME_MAX-VOLUME_MIN)+1]
209+
controlVariablesSizes = [(CONTROL_MAX-CONTROL_MIN)+1]
210+
totalStateSpaceSize = stateVariablesSizes[1]
211+
totalControlSpaceSize = controlVariablesSizes[1]
212+
monteCarloSize = 10
213+
214+
model = StochDynProgModel(N_STAGES-1,
215+
N_CONTROLS,
216+
N_STATES,
217+
N_NOISES,
218+
x_bounds,
219+
u_bounds,
220+
x0,
221+
cost_t_DH,
222+
finalCostFunction,
223+
dynamic_DH,
224+
constraints,
225+
aleas)
226+
227+
params = SDPparameters(stateSteps, controlSteps, totalStateSpaceSize,
228+
totalControlSpaceSize, stateVariablesSizes,
229+
controlVariablesSizes, monteCarloSize, infoStruct)
230+
231+
return model, params
232+
end
233+
234+
235+
"""Solve the problem."""
236+
function solve_dams_sdp_DH(display=false)
237+
model, params = init_problem_sdp_DH()
238+
239+
law = model.noises
240+
241+
V = sdp_optimize(model, params, display)
242+
243+
scenar = Array(Array, N_STAGES-1)
244+
245+
for t in 1:(N_STAGES-1)
246+
scenar[t] = sampling(law, t)
247+
end
248+
249+
costs, stocks, controls = sdp_forward_simulation(model, params,
250+
scenar, X0, V, true)
251+
252+
println("SDP DH cost: ", costs)
253+
return costs, stocks, controls, scenar, V
254+
end
255+
256+
function solve_dams_sdp_HD(display=false)
257+
model, params = init_problem_sdp_HD()
258+
259+
law = model.noises
260+
261+
V = sdp_optimize(model, params, display)
262+
263+
scenar = Array(Array, (N_STAGES-1))
264+
265+
for t in 1:(N_STAGES-1)
266+
scenar[t] = sampling(law, t)
267+
end
268+
269+
costs, stocks, controls = sdp_forward_simulation(model, params,
270+
scenar, X0, V, true)
271+
272+
println("SDP HD cost: ", costs)
273+
return costs, stocks, controls, scenar, V
274+
end
275+
276+
277+
function compare_sdp_DH_HD(display=false)
278+
modelHD, paramsHD = init_problem_sdp_HD()
279+
modelDH, paramsDH = init_problem_sdp_DH()
280+
281+
law = modelHD.noises
282+
283+
scenar = Array(Array, (N_STAGES-1))
284+
285+
for t in 1:(N_STAGES-1)
286+
scenar[t] = sampling(law, t)
287+
end
288+
289+
VHD = sdp_optimize(modelHD, paramsHD, display)
290+
291+
costHD, stocksHD, controlsHD = sdp_forward_simulation(modelHD, paramsHD,
292+
scenar, X0, VHD, true)
293+
294+
VDH = sdp_optimize(modelDH, paramsDH, display)
295+
296+
costDH, stocksDH, controlsDH = sdp_forward_simulation(modelDH, paramsDH,
297+
scenar, X0, VDH, true)
298+
299+
return costHD, stocksHD, controlsHD, costDH, stocksDH, controlsDH, scenar
300+
end
301+
302+
function init_problem()
303+
304+
x0 = X0
305+
aleas = generate_probability_laws()
306+
307+
x_bounds = [(VOLUME_MIN, VOLUME_MAX)]
308+
u_bounds = [(CONTROL_MIN, CONTROL_MAX), (0, VOLUME_MAX)]
309+
310+
N_CONTROLS = 2
311+
N_STATES = 1
312+
N_ALEAS = 1
313+
314+
model = LinearDynamicLinearCostSPmodel(N_STAGES,
315+
u_bounds,
316+
x0,
317+
cost_t,
318+
dynamic,
319+
aleas)
320+
321+
set_state_bounds(model, x_bounds);
322+
323+
solver = SOLVER
324+
325+
params = SDDPparameters(solver, N_SCENARIOS, EPSILON, MAX_ITER)
326+
327+
return model, params
328+
end
329+
330+
function solve_dams(display=false)
331+
model, params = init_problem()
332+
333+
V, pbs = solve_SDDP(model, params, display)
334+
335+
params.forwardPassNumber = 1
336+
337+
aleas = simulate_scenarios(model.noises,
338+
(model.stageNumber,
339+
params.forwardPassNumber,
340+
model.dimNoises))
341+
342+
costs, stocks, controls = forward_simulations(model, params, V, pbs, aleas)
343+
344+
println("SDDP cost: ", costs)
345+
return stocks, V, controls, aleas
346+
end
347+
348+
349+
function compare_SDDP_SDP(display=false)
350+
351+
modelHD, paramsHD = init_problem_sdp_HD()
352+
modelDH, paramsDH = init_problem_sdp_DH()
353+
model, params = init_problem()
354+
355+
params.forwardPassNumber = 1
356+
357+
aleas = simulate_scenarios(model.noises,
358+
(model.stageNumber-1,
359+
params.forwardPassNumber,
360+
model.dimNoises))
361+
362+
V, pbs = solve_SDDP(model, params, display)
363+
364+
costs, stocks, controls = forward_simulations(model, params, V, pbs, aleas)
365+
366+
VHD = sdp_optimize(modelHD, paramsHD, display)
367+
368+
costHD, stocksHD, controlsHD = sdp_forward_simulation(modelHD, paramsHD,
369+
aleas, X0, VHD, true)
370+
371+
VDH = sdp_optimize(modelDH, paramsDH, display)
372+
373+
costDH, stocksDH, controlsDH = sdp_forward_simulation(modelDH, paramsDH,
374+
aleas, X0, VDH, true)
375+
376+
return costs, stocks, controls, aleas, costHD, stocksHD, controlsHD, costDH, stocksDH, controlsDH
377+
end

0 commit comments

Comments
 (0)