@@ -37,6 +37,9 @@ fulfilled.
3737
3838"""
3939function solve_SDDP (model:: SPModel , param:: SDDPparameters , verbose= 0 :: Int64 )
40+ if model. IS_SMIP && isa (param. MIPSOLVER, Void)
41+ error (" MIP solver is not defined. Please set `param.MIPSOLVER`" )
42+ end
4043 # initialize value functions:
4144 V, problems = initialize_value_functions (model, param)
4245 (verbose > 0 ) && println (" Initial value function loaded into memory." )
4750
4851
4952function solve_SDDP (model:: SPModel , param:: SDDPparameters , V:: Vector{PolyhedralFunction} , verbose= 0 :: Int64 )
53+ if model. IS_SMIP && isa (param. MIPSOLVER, Void)
54+ error (" MIP solver is not defined. Please set `param.MIPSOLVER`" )
55+ end
5056 # First step: process value functions if hotstart is called
5157 problems = hotstart_SDDP (model, param, V)
5258 sddp_stats = run_SDDP! (model, param, V, problems, verbose)
@@ -191,11 +197,8 @@ function estimate_upper_bound(model::SPModel, param::SDDPparameters,
191197 problem:: Vector{JuMP.Model} ,
192198 n_simulation= 1000 :: Int )
193199 aleas = simulate_scenarios (model. noises, n_simulation)
194- costs, stockTrajectories, _ = forward_simulations (model, param, problem, aleas)
195- return upper_bound (costs), costs
200+ return estimate_upper_bound (model, param, aleas, problem)
196201end
197-
198-
199202function estimate_upper_bound (model:: SPModel , param:: SDDPparameters ,
200203 aleas:: Array{Float64, 3} ,
201204 problem:: Vector{JuMP.Model} )
@@ -204,12 +207,6 @@ function estimate_upper_bound(model::SPModel, param::SDDPparameters,
204207end
205208
206209
207- """ Build a collection of cuts initialized at 0"""
208- function get_null_value_functions_array (model:: SPModel )
209- return [PolyhedralFunction (zeros (1 ), zeros (1 , model. dimStates), 1 ) for i in 1 : model. stageNumber]
210- end
211-
212-
213210"""
214211Build a cut approximating terminal cost with null function
215212
@@ -257,33 +254,35 @@ function build_models(model::SPModel, param::SDDPparameters)
257254end
258255
259256function build_model (model, param, t)
260- m = Model (solver= param. solver )
257+ m = Model (solver= param. SOLVER )
261258
262259 nx = model. dimStates
263260 nu = model. dimControls
264261 nw = model. dimNoises
265262
263+ # define variables in JuMP:
266264 @variable (m, model. xlim[i][1 ] <= x[i= 1 : nx] <= model. xlim[i][2 ])
267- @variable (m, model. ulim[i][1 ] <= u[i= 1 : nu] <= model. ulim[i][2 ])
268265 @variable (m, model. xlim[i][1 ] <= xf[i= 1 : nx]<= model. xlim[i][2 ])
266+ @variable (m, model. ulim[i][1 ] <= u[i= 1 : nu] <= model. ulim[i][2 ])
269267 @variable (m, alpha)
270268
271269 @variable (m, w[1 : nw] == 0 )
272270 m. ext[:cons ] = @constraint (m, state_constraint, x .== 0 )
273271
274272 @constraint (m, xf .== model. dynamics (t, x, u, w))
275273
274+ # Add equality and inequality constraints:
276275 if model. equalityConstraints != nothing
277276 @constraint (m, model. equalityConstraints (t, x, u, w) .== 0 )
278277 end
279278 if model. inequalityConstraints != nothing
280279 @constraint (m, model. inequalityConstraints (t, x, u, w) .<= 0 )
281280 end
282281
283- if typeof (model) == LinearDynamicLinearCostSPmodel
282+ # Define objective function (could be linear or piecewise linear)
283+ if isa (model. costFunctions, Function)
284284 @objective (m, Min, model. costFunctions (t, x, u, w) + alpha)
285-
286- elseif typeof (model) == PiecewiseLinearCostSPmodel
285+ elseif isa (model. costFunctions, Vector{Function})
287286 @variable (m, cost)
288287
289288 for i in 1 : length (model. costFunctions)
@@ -292,6 +291,11 @@ function build_model(model, param, t)
292291 @objective (m, Min, cost + alpha)
293292 end
294293
294+ # Add binary variable if problem is a SMIP:
295+ if model. IS_SMIP
296+ m. colCat[2 * nx+ 1 : 2 * nx+ nu] = model. controlCat
297+ end
298+
295299 return m
296300end
297301
@@ -319,7 +323,7 @@ function initialize_value_functions(model::SPModel,
319323
320324 solverProblems = build_models (model, param)
321325 V = PolyhedralFunction[
322- PolyhedralFunction ([], Array {Float64} ( 0 , model. dimStates), 0 ) for i in 1 : model. stageNumber]
326+ PolyhedralFunction (model. dimStates) for i in 1 : model. stageNumber]
323327
324328 # Build scenarios according to distribution laws:
325329 aleas = simulate_scenarios (model. noises, param. forwardPassNumber)
@@ -399,7 +403,7 @@ Bellman value (Float64)
399403function get_bellman_value (model:: SPModel , param:: SDDPparameters ,
400404 t:: Int64 , Vt:: PolyhedralFunction , xt:: Vector{Float64} )
401405
402- m = Model (solver= param. solver )
406+ m = Model (solver= param. SOLVER )
403407 @variable (m, alpha)
404408
405409 for i in 1 : Vt. numCuts
@@ -515,7 +519,7 @@ function exact_prune_cuts(model::SPModel, params::SDDPparameters, V::PolyhedralF
515519 ncuts = V. numCuts
516520 # Find all active cuts:
517521 if ncuts > 1
518- active_cuts = Bool[is_cut_relevant (model, i, V, params. solver ) for i= 1 : ncuts]
522+ active_cuts = Bool[is_cut_relevant (model, i, V, params. SOLVER ) for i= 1 : ncuts]
519523 return PolyhedralFunction (V. betas[active_cuts], V. lambdas[active_cuts, :], sum (active_cuts))
520524 else
521525 return V
0 commit comments