Skip to content

Commit cbe4f44

Browse files
committed
[UPD] Add a proper switch to cuts pruning
1 parent 76ae060 commit cbe4f44

File tree

4 files changed

+48
-31
lines changed

4 files changed

+48
-31
lines changed

src/SDDPoptimize.jl

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,14 @@ function run_SDDP!(model::SPModel,
108108

109109
#Initialization of the counter
110110
stats = SDDPStat()
111-
activecuts = (param.pruning[:type] ["level1", "exact+"])? [ActiveCutsContainer(model.dimStates) for i in 1:model.stageNumber-1]: nothing
111+
112+
# Initialize cuts container for cuts pruning:
113+
if isa(param.pruning[:type], Union{Type{Territory}, Type{LevelOne}})
114+
activecuts = [ActiveCutsContainer(model.dimStates) for i in 1:model.stageNumber-1]
115+
else
116+
activecuts = [nothing for i in 1:model.stageNumber-1]
117+
end
118+
112119
(verbose > 0) && println("Initialize cuts")
113120

114121
# If computation of upper-bound is needed, a set of scenarios is built

src/cutpruning.jl

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#############################################################################
77

88
type ActiveCutsContainer
9-
ncuts::Int
9+
numCuts::Int
1010
territories::Array{Array} #set of states where cut k is active
1111
nstates::Int
1212
states::Array{Float64, 2} #set of states where cuts are tested
@@ -59,15 +59,15 @@ function prune_cuts!(model::SPModel,
5959
param::SDDPparameters,
6060
V::Vector{PolyhedralFunction},
6161
trajectories::Array{Float64, 3},
62-
territory::Union{Void, Array{ActiveCutsContainer}},
62+
territory::Union{Array{Void}, Array{ActiveCutsContainer}},
6363
it::Int64,
6464
verbose::Int64)
6565
# Basic pruning: remove redundant cuts
6666
remove_redundant_cuts!(V)
6767

6868
# If pruning is performed with territory heuristic, update territory
6969
# at given iteration:
70-
if param.pruning[:type] ["level1", "exact+"]
70+
if isa(param.pruning[:type], Union{Type{Territory}, Type{LevelOne}})
7171
for t in 1:model.stageNumber-1
7272
states = reshape(trajectories[t, :, :], param.forwardPassNumber, model.dimStates)
7373
find_level1_cuts!(territory[t], V[t], states)
@@ -81,16 +81,7 @@ function prune_cuts!(model::SPModel,
8181
(verbose > 0) && print("Prune cuts ...")
8282

8383
for i in 1:length(V)-1
84-
if param.pruning[:type] == "exact"
85-
# apply exact cuts pruning:
86-
V[i] = exact_cuts_pruning(model, param, V[i])
87-
elseif param.pruning[:type] == "level1"
88-
# apply heuristic to prune cuts:
89-
V[i] = level1_cuts_pruning!(territory[i], V[i])
90-
elseif param.pruning[:type] == "exact+"
91-
# apply heuristicly accelerated exact pruning:
92-
V[i] = exact_cuts_pruning_accelerated!(model, territory[i], V[i], param.SOLVER)
93-
end
84+
V[i] = pcuts!(param.pruning[:type], model, param, V[i], territory[i])
9485
end
9586

9687
# final number of cuts:
@@ -100,6 +91,10 @@ function prune_cuts!(model::SPModel,
10091
end
10192
end
10293

94+
pcuts!(::Type{LevelOne}, model, param, V, territory) = level1_cuts_pruning!(model, param, V, territory)
95+
pcuts!(::Type{ExactPruning}, model, param, V, territory) = exact_cuts_pruning(model, param, V, territory)
96+
pcuts!(::Type{Territory}, model, param, V, territory) = exact_cuts_pruning_accelerated!(model, param, V, territory)
97+
10398

10499
"""
105100
Remove useless cuts in PolyhedralFunction.
@@ -113,7 +108,7 @@ Remove useless cuts in PolyhedralFunction.
113108
# Return
114109
* `PolyhedralFunction`: pruned polyhedral function
115110
"""
116-
function exact_cuts_pruning(model::SPModel, param::SDDPparameters, V::PolyhedralFunction)
111+
function exact_cuts_pruning(model::SPModel, param::SDDPparameters, V::PolyhedralFunction, territory)
117112
ncuts = V.numCuts
118113
# Find all active cuts:
119114
if ncuts > 1
@@ -175,7 +170,7 @@ ActiveCutsContainer(ndim) = ActiveCutsContainer(0, [], 0, Array{Float64}(0, ndim
175170
# Arguments
176171
* `cutscontainer::ActiveCutsContainer`:
177172
* `Vt::PolyhedralFunction`:
178-
Object storing all cuts
173+
Object storing all cuts
179174
* `states`:
180175
Object storing all visited states
181176
"""
@@ -206,8 +201,8 @@ end
206201
# Arguments
207202
* `cutscontainer::ActiveCutsContainer`:
208203
* `V::PolyhedralFunction`:
209-
Object storing all cuts
210-
* `indcut::Int64`:
204+
Object storing all cuts
205+
* `indcut::Int64`:
211206
new cut index
212207
"""
213208
function update_territory!(cutscontainer::ActiveCutsContainer, V::PolyhedralFunction, indcut::Int64)
@@ -256,12 +251,13 @@ end
256251
# Arguments
257252
* `cutscontainer::ActiveCutsContainer`:
258253
* `V::PolyhedralFunction`:
259-
Object storing all cuts
254+
Object storing all cuts
260255
# Return
261256
* `V::PolyhedralFunction`
262257
the new PolyhedralFunction
263258
"""
264-
function level1_cuts_pruning!(cutscontainer::ActiveCutsContainer, V::PolyhedralFunction)
259+
function level1_cuts_pruning!(model::SPModel, param::SDDPparameters,
260+
V::PolyhedralFunction, cutscontainer::ActiveCutsContainer)
265261
assert(cutscontainer.numCuts == V.numCuts)
266262

267263
nstates = [length(terr) for terr in cutscontainer.territories]
@@ -284,16 +280,18 @@ then test remaining cuts.
284280
* `model::SPModel`:
285281
* `cutscontainer::ActiveCutsContainer`:
286282
* `V::PolyhedralFunction`:
287-
Object storing all cuts
288-
283+
Object storing all cuts
284+
289285
# Return
290286
* `V::PolyhedralFunction`
291287
the new PolyhedralFunction
292288
"""
293-
function exact_cuts_pruning_accelerated!(model::SPModel,
294-
cutscontainer::ActiveCutsContainer,
295-
V::PolyhedralFunction, solver)
289+
function exact_cuts_pruning_accelerated!(model::SPModel, param::SDDPparameters,
290+
V::PolyhedralFunction,
291+
cutscontainer::ActiveCutsContainer)
292+
296293
assert(cutscontainer.numCuts == V.numCuts)
294+
solver = param.SOLVER
297295

298296
nstates = [length(terr) for terr in cutscontainer.territories]
299297
# Set of inactive cuts:
@@ -326,8 +324,8 @@ end
326324
# Arguments
327325
* `xf::Vector{Float64}`:
328326
* `V::PolyhedralFunction`:
329-
Object storing all cuts
330-
327+
Object storing all cuts
328+
331329
# Return
332330
`bestcost::Float64`
333331
Value of maximal cut at point `xf`

src/objects.jl

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,11 @@ type StochDynProgModel <: SPModel
138138

139139
end
140140

141-
141+
# Define alias for cuts pruning algorithm:
142+
typealias LevelOne Val{:LevelOne}
143+
typealias ExactPruning Val{:Exact}
144+
typealias Territory Val{:Exact_Plus}
145+
typealias NoPruning Val{:none}
142146

143147
type SDDPparameters
144148
# Solver used to solve LP
@@ -178,7 +182,15 @@ type SDDPparameters
178182
accparams = is_acc? Dict(:ρ0=>rho0, :alpha=>alpha, :rho=>rho0): Dict()
179183

180184
pruning_algo = (prune_cuts>0)? pruning_algo: "none"
181-
prune_cuts = Dict(:pruning=>prune_cuts>0, :period=>prune_cuts, :type=>pruning_algo)
185+
prune_cuts = (pruning_algo != "none")? prune_cuts: 0
186+
187+
corresp = Dict("none"=>NoPruning,
188+
"level1"=>LevelOne,
189+
"exact+"=>Territory,
190+
"exact"=>ExactPruning)
191+
prune_cuts = Dict(:pruning=>prune_cuts>0,
192+
:period=>prune_cuts,
193+
:type=>corresp[pruning_algo])
182194
return new(solver, mipsolver, passnumber, gap,
183195
max_iterations, prune_cuts, compute_ub,
184196
montecarlo_final, montecarlo_in_iter, is_acc, accparams)

test/sddp.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,13 @@ facts("SDDP algorithm: 1D case") do
120120

121121
terr = StochDynamicProgramming.ActiveCutsContainer(2)
122122
StochDynamicProgramming.find_level1_cuts!(terr, vt, [0. 0.; 1. 0.])
123-
@fact terr.ncuts --> 2
123+
@fact terr.numCuts --> 2
124124
@fact terr.nstates --> 2
125125
@fact length(terr.territories[1]) --> 2
126126
@fact length(terr.territories[2]) --> 0
127127

128128
# Check heuristic removal:
129-
vt2 = StochDynamicProgramming.level1_cuts_pruning!(terr, vt)
129+
vt2 = StochDynamicProgramming.level1_cuts_pruning!(model, param, vt, terr)
130130
@fact isa(vt2, StochDynamicProgramming.PolyhedralFunction) --> true
131131
@fact vt2.numCuts --> 1
132132
@fact vt2.betas[1] --> vt.betas[1]

0 commit comments

Comments
 (0)