Skip to content

Commit f3f8460

Browse files
committed
[UPD] Integrate random dynamic
1 parent 71d33c5 commit f3f8460

File tree

2 files changed

+239
-5
lines changed

2 files changed

+239
-5
lines changed

examples/dynamic_example.jl

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
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+
# Test SDDP with dam example
7+
# Source: Adrien Cassegrain
8+
#############################################################################
9+
10+
#srand(2713)
11+
push!(LOAD_PATH, "../src")
12+
13+
using StochDynamicProgramming, JuMP, Clp
14+
15+
#Constant that the user have to define himself
16+
const SOLVER = ClpSolver()
17+
# const SOLVER = CplexSolver(CPX_PARAM_SIMDISPLAY=0)
18+
19+
const N_STAGES = 5
20+
const N_SCENARIOS = 3
21+
22+
const DIM_STATES = 2
23+
const DIM_CONTROLS = 2
24+
const DIM_ALEAS = 1
25+
26+
27+
28+
#Constants that the user does not have to define
29+
const T0 = 1
30+
31+
# Constants:
32+
const VOLUME_MAX = 100
33+
const VOLUME_MIN = 0
34+
35+
const CONTROL_MAX = round(Int, .4/7. * VOLUME_MAX) + 1
36+
const CONTROL_MIN = 0
37+
38+
const W_MAX = round(Int, .5/7. * VOLUME_MAX)
39+
const W_MIN = 0
40+
const DW = 1
41+
42+
# Define aleas' space:
43+
const N_ALEAS = Int(round(Int, (W_MAX - W_MIN) / DW + 1))
44+
const ALEAS = linspace(W_MIN, W_MAX, N_ALEAS)
45+
46+
const EPSILON = .05
47+
const MAX_ITER = 20
48+
49+
alea_year = Array([7.0 7.0 8.0 3.0 1.0 1.0 3.0 4.0 3.0 2.0 6.0 5.0 2.0 6.0 4.0 7.0 3.0 4.0 1.0 1.0 6.0 2.0 2.0 8.0 3.0 7.0 3.0 1.0 4.0 2.0 4.0 1.0 3.0 2.0 8.0 1.0 5.0 5.0 2.0 1.0 6.0 7.0 5.0 1.0 7.0 7.0 7.0 4.0 3.0 2.0 8.0 7.0])
50+
51+
const X0 = [50, 50]
52+
53+
Ax=[]
54+
Au=[]
55+
Aw=[]
56+
57+
Cx=[]
58+
Cu=[]
59+
Cw=[]
60+
61+
function generate_random_dynamic()
62+
for i=1:N_STAGES
63+
push!(Ax, rand(DIM_STATES,DIM_STATES))
64+
push!(Au, rand(DIM_STATES,DIM_CONTROLS))
65+
push!(Aw, rand(DIM_STATES,DIM_ALEAS))
66+
end
67+
end
68+
69+
function generate_random_costs()
70+
for i=1:N_STAGES
71+
push!(Cx, rand(1,DIM_STATES))
72+
push!(Cu, -1*rand(1,DIM_CONTROLS))
73+
push!(Cw, rand(1,DIM_ALEAS))
74+
end
75+
end
76+
77+
generate_random_dynamic()
78+
generate_random_costs()
79+
80+
# Define dynamic of the dam:
81+
function dynamic(t, x, u, w)
82+
return Ax[t]*x+Au[t]*u+Aw[t]*w
83+
end
84+
85+
# Define cost corresponding to each timestep:
86+
function cost_t(t, x, u, w)
87+
#if you want to compare the value, take the cost with only control
88+
return (Cu[t]*u)[1,1]
89+
#return (Cx[t]*x)[1,1]+(Cu[t]*u)[1,1]+(Cw[t]*w)[1,1]
90+
end
91+
92+
93+
"""Build aleas probabilities for each month."""
94+
function build_aleas()
95+
aleas = zeros(N_ALEAS, N_STAGES)
96+
97+
# take into account seasonality effects:
98+
unorm_prob = linspace(1, N_ALEAS, N_ALEAS)
99+
proba1 = unorm_prob / sum(unorm_prob)
100+
proba2 = proba1[N_ALEAS:-1:1]
101+
102+
for t in 1:N_STAGES
103+
aleas[:, t] = (1 - sin(pi*t/N_STAGES)) * proba1 + sin(pi*t/N_STAGES) * proba2
104+
end
105+
return aleas
106+
end
107+
108+
109+
"""Build an admissible scenario for water inflow."""
110+
function build_scenarios(n_scenarios::Int64, probabilities)
111+
scenarios = zeros(n_scenarios, N_STAGES)
112+
113+
for scen in 1:n_scenarios
114+
for t in 1:N_STAGES
115+
Pcum = cumsum(probabilities[:, t])
116+
117+
n_random = rand()
118+
prob = findfirst(x -> x > n_random, Pcum)
119+
scenarios[scen, t] = prob
120+
end
121+
end
122+
return scenarios
123+
end
124+
125+
126+
"""Build probability distribution at each timestep.
127+
128+
Return a Vector{NoiseLaw}"""
129+
function generate_probability_laws()
130+
aleas = build_scenarios(N_SCENARIOS, build_aleas())
131+
132+
laws = Vector{NoiseLaw}(N_STAGES)
133+
134+
# uniform probabilities:
135+
proba = 1/N_SCENARIOS*ones(N_SCENARIOS)
136+
137+
for t=1:N_STAGES
138+
laws[t] = NoiseLaw(aleas[:, t], proba)
139+
end
140+
141+
return laws
142+
end
143+
144+
145+
"""Instantiate the problem."""
146+
function init_problem()
147+
148+
x0 = X0
149+
aleas = generate_probability_laws()
150+
151+
x_bounds = [(VOLUME_MIN, VOLUME_MAX), (VOLUME_MIN, VOLUME_MAX)]
152+
u_bounds = []
153+
for u = 1:DIM_CONTROLS
154+
u_bounds = push!(u_bounds, (CONTROL_MIN, CONTROL_MAX))
155+
end
156+
157+
model = LinearDynamicLinearCostSPmodel(N_STAGES,
158+
u_bounds,
159+
x0,
160+
cost_t,
161+
dynamic,
162+
aleas)
163+
164+
#set_state_bounds(model, x_bounds)
165+
166+
solver = SOLVER
167+
params = SDDPparameters(solver, N_SCENARIOS, EPSILON, MAX_ITER)
168+
169+
return model, params
170+
end
171+
172+
model, params = init_problem()
173+
modelbis = model
174+
paramsbis = params
175+
176+
177+
"""Solve the problem."""
178+
function solve_dams(model,params,display=false)
179+
180+
#model, params = init_problem()
181+
182+
V, pbs = solve_SDDP(model, params, display)
183+
184+
aleas = simulate_scenarios(model.noises,
185+
(model.stageNumber,
186+
params.forwardPassNumber,
187+
model.dimNoises))
188+
189+
params.forwardPassNumber = 1
190+
191+
costs, stocks = forward_simulations(model, params, V, pbs, aleas)
192+
println("SDDP cost: ", costs)
193+
return stocks, V
194+
end
195+
196+
#Solve the problem and try nb_iter times to generate radom data in case of infeasibility
197+
unsolve = true
198+
sol = 0
199+
i = 0
200+
nb_iter = 10
201+
202+
while i<nb_iter
203+
sol, status = extensive_formulation(model,params)
204+
if (status == :Optimal)
205+
unsolve = false
206+
break
207+
else
208+
println("\nGenerate new dynamic to reach feasability\n")
209+
Ax=[]
210+
Au=[]
211+
Aw=[]
212+
generate_random_dynamic()
213+
model, params = init_problem()
214+
modelbis = model
215+
paramsbis = params
216+
i = i+1
217+
end
218+
end
219+
220+
221+
if (unsolve)
222+
println("Change your parameters")
223+
else
224+
a,b = solve_dams(modelbis,paramsbis)
225+
println("solution =",sol)
226+
end
227+

src/extensiveFormulation.jl

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
# Define the extensive formulation to check the results of small problems
77
#############################################################################
88

9-
9+
"""
10+
Contruct the scenario tree and solve the problem with measurability constraints
11+
"""
1012
function extensive_formulation(model,
1113
params)
1214

1315

14-
#TODO Recover all the constant in the model or in param
16+
#Recover all the constant in the model or in param
1517
laws = model.noises
1618
N_NOISES = laws[1].supportSize
1719

@@ -43,7 +45,6 @@ function extensive_formulation(model,
4345

4446

4547
#Computes the total probability of each node from the conditional probabilities
46-
#proba = Any[]
4748
proba = []
4849
push!(proba, laws[1].proba)
4950
for t = 2 : T
@@ -64,14 +65,18 @@ function extensive_formulation(model,
6465
for xi = 1 : laws[t].supportSize
6566
m = (n-1)*laws[t].supportSize+xi
6667

68+
#Add bounds constraint on the control
6769
@addConstraint(mod,[u[t,DIM_CONTROL*(m-1)+k] for k = 1:DIM_CONTROL] .>= [model.ulim[k][1] for k = 1:DIM_CONTROL])
6870
@addConstraint(mod,[u[t,DIM_CONTROL*(m-1)+k] for k = 1:DIM_CONTROL] .<= [model.ulim[k][2] for k = 1:DIM_CONTROL])
69-
71+
72+
#Add dynamic constraints
7073
@addConstraint(mod,
7174
[x[t+1,DIM_STATE*(m-1)+k] for k = 1:DIM_STATE] .== model.dynamics(t,
7275
[x[t,DIM_STATE*(n-1)+k] for k = 1:DIM_STATE],
7376
[u[t,DIM_CONTROL*(m-1)+k] for k = 1:DIM_CONTROL],
7477
laws[t].support[xi]))
78+
79+
#Add constraints to define the cost at each node
7580
@addConstraint(mod,
7681
c[t,m] == model.costFunctions(t,
7782
[x[t,DIM_STATE*(n-1)+k] for k = 1:DIM_STATE],
@@ -93,7 +98,9 @@ function extensive_formulation(model,
9398
solved = (status == :Optimal)
9499

95100
if solved
96-
return getObjectiveValue(mod)
101+
return getObjectiveValue(mod), status
102+
else
103+
return -1., status
97104
end
98105

99106
end

0 commit comments

Comments
 (0)