@@ -34,22 +34,22 @@ fulfilled.
3434 each value function
3535* `count_callsolver::Int64`:
3636 number of times the solver has been called
37-
37+
3838"""
3939function solve_SDDP (model:: SPModel , param:: SDDPparameters , display= 0 :: Int64 )
4040 # initialize value functions:
4141 V, problems = initialize_value_functions (model, param)
4242 # Run SDDP upon example:
43- count_callsolver = run_SDDP! (model, param, V, problems, display)
44- return V, problems, count_callsolver
43+ sddp_stats = run_SDDP! (model, param, V, problems, display)
44+ return V, problems, sddp_stats
4545end
4646
4747
4848function solve_SDDP (model:: SPModel , param:: SDDPparameters , V:: Vector{PolyhedralFunction} , display= 0 :: Int64 )
4949 # First step: process value functions if hotstart is called
5050 problems = hotstart_SDDP (model, param, V)
51- count_callsolver = run_SDDP! (model, param, V, problems, display)
52- return V, problems, count_callsolver
51+ sddp_stats = run_SDDP! (model, param, V, problems, display)
52+ return V, problems, sddp_stats
5353end
5454
5555
@@ -61,7 +61,7 @@ function run_SDDP!(model::SPModel,
6161 display= 0 :: Int64 )
6262
6363 # Initialization of the counter
64- count_callsolver :: Int = 0
64+ stats = SDDPStat ( 0 , [], [], [], 0 )
6565
6666 if display > 0
6767 println (" Initialize cuts" )
@@ -77,10 +77,9 @@ function run_SDDP!(model::SPModel,
7777 iteration_count:: Int64 = 0
7878
7979 while (iteration_count < param. maxItNumber) & (~ stopping_test)
80+
8081 # Time execution of current pass:
81- if display > 0
82- tic ()
83- end
82+ tic ()
8483
8584 # Build given number of scenarios according to distribution
8685 # law specified in model.noises:
@@ -103,32 +102,37 @@ function run_SDDP!(model::SPModel,
103102 false )
104103
105104 # Update the number of call
106- count_callsolver += callsolver_forward + callsolver_backward
105+ stats . ncallsolver += callsolver_forward + callsolver_backward
107106
108107 iteration_count += 1
108+ stats. niterations += 1
109109
110110 if (param. compute_cuts_pruning > 0 ) && (iteration_count% param. compute_cuts_pruning== 0 )
111111 (display > 0 ) && println (" Prune cuts ..." )
112112 remove_redundant_cuts! (V)
113113 prune_cuts! (model, param, V)
114114 problems = hotstart_SDDP (model, param, V)
115115 end
116+ lwb = get_bellman_value (model, param, 1 , V[1 ], model. initialState)
117+ push! (stats. lower_bounds, lwb)
116118
117119 if (param. compute_upper_bound > 0 ) && (iteration_count% param. compute_upper_bound== 0 )
118120 (display > 0 ) && println (" Compute upper-bound with " ,
119121 param. monteCarloSize, " scenarios..." )
120122 upb, costs = estimate_upper_bound (model, param, upperbound_scenarios, problems)
121123 if param. gap > 0.
122- lwb = get_bellman_value (model, param, 1 , V[1 ], model. initialState)
123124 stopping_test = test_stopping_criterion (lwb, upb, param. gap)
124125 end
125126 end
126127
128+ push! (stats. exectime, toq ())
129+ push! (stats. upper_bounds, upb)
130+
127131 if (display > 0 ) && (iteration_count% display== 0 )
128132 println (" Pass number " , iteration_count,
129133 " \t Upper-bound: " , upb,
130- " \t Lower-bound: " , round (get_bellman_value (model, param, 1 , V[ 1 ], model . initialState), 4 ),
131- " \t Time: " , round (toq (), 2 )," s" )
134+ " \t Lower-bound: " , round (stats . lower_bounds[ end ], 4 ),
135+ " \t Time: " , round (stats . exectime[ end ], 2 )," s" )
132136 end
133137
134138 end
@@ -149,7 +153,7 @@ function run_SDDP!(model::SPModel,
149153 round (mean (costs),4 ), " +/- " , round (1.96 * std (costs)/ sqrt (length (costs)),4 ))
150154 end
151155
152- return count_callsolver
156+ return stats
153157end
154158
155159
@@ -180,15 +184,11 @@ function estimate_upper_bound(model::SPModel, param::SDDPparameters,
180184 n_simulation= 1000 :: Int )
181185
182186 aleas = simulate_scenarios (model. noises, n_simulation)
183-
184- callsolver:: Int = 0
185- costs, stockTrajectories, _ = forward_simulations (model,
186- param,
187- problem,
188- aleas)
189-
187+ costs, stockTrajectories, _ = forward_simulations (model, param, problem, aleas)
190188 return upper_bound (costs), costs
191189end
190+
191+
192192function estimate_upper_bound (model:: SPModel , param:: SDDPparameters ,
193193 aleas:: Array{Float64, 3} ,
194194 problem:: Vector{JuMP.Model} )
199199
200200""" Build a collection of cuts initialized at 0"""
201201function get_null_value_functions_array (model:: SPModel )
202-
203- V = Vector {PolyhedralFunction} (model. stageNumber)
204- for t = 1 : model. stageNumber
205- V[t] = PolyhedralFunction (zeros (1 ), zeros (1 , model. dimStates), 1 )
206- end
207-
208- return V
202+ return [PolyhedralFunction (zeros (1 ), zeros (1 , model. dimStates), 1 ) for i in 1 : model. stageNumber]
209203end
210204
211205
@@ -298,7 +292,6 @@ function build_models(model::SPModel, param::SDDPparameters)
298292end
299293
300294
301-
302295"""
303296Initialize value functions along a given trajectory
304297
@@ -461,7 +454,8 @@ Compute optimal control at point xt and time t.
461454# Return
462455 `Vector{Float64}`: optimal control at time t
463456"""
464- function get_control (model:: SPModel , param:: SDDPparameters , lpproblem:: Vector{JuMP.Model} , t:: Int , xt:: Vector{Float64} , xi:: Vector{Float64} )
457+ function get_control (model:: SPModel , param:: SDDPparameters , lpproblem:: Vector{JuMP.Model} ,
458+ t:: Int , xt:: Vector{Float64} , xi:: Vector{Float64} )
465459 return solve_one_step_one_alea (model, param, lpproblem[t], t, xt, xi)[2 ]. optimal_control
466460end
467461
@@ -565,3 +559,4 @@ function is_cut_relevant(model::SPModel, k::Int, Vt::PolyhedralFunction, solver;
565559 sol = getobjectivevalue (m)
566560 return sol < epsilon
567561end
562+
0 commit comments