Skip to content

Commit 307d1d1

Browse files
committed
[REF] Update naming to be more explicit
1 parent f39c73f commit 307d1d1

File tree

5 files changed

+63
-68
lines changed

5 files changed

+63
-68
lines changed

examples/damsvalley.jl

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ function init_problem()
110110
model = LinearSPModel(N_STAGES, u_bounds,
111111
X0, cost_t,
112112
dynamic, aleas,
113-
final_cost_dams)
113+
Vfinal=final_cost_dams)
114114

115115
# Add bounds for stocks:
116116
set_state_bounds(model, x_bounds)
@@ -121,17 +121,11 @@ function init_problem()
121121
params = SDDPparameters(solver,
122122
passnumber=FORWARD_PASS,
123123
gap=EPSILON,
124-
pruning_algo="exact",
125-
max_iterations=20,
126-
prune_cuts=10)
124+
max_iterations=MAX_ITER)
127125
return model, params
128126
end
129127

130128
# Solve the problem:
131129
model, params = init_problem()
132130
V, pbs = @time solve_SDDP(model, params, 1)
133-
aleas = simulate_scenarios(model.noises, 100)
134-
c, x, u = forward_simulations(model, params, pbs, aleas);
135131

136-
xx = reshape(x[5, :, :], 100, 5)
137-
v = V[5]

src/SDDPoptimize.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ function run_SDDP!(model::SPModel,
108108

109109
#Initialization of the counter
110110
stats = SDDPStat()
111-
territory = (param.pruning[:type] ["territory", "mixed"])? [Territories(model.dimStates) for i in 1:model.stageNumber-1]: nothing
111+
activecuts = (param.pruning[:type] ["level1", "exact+"])? [ActiveCutsContainer(model.dimStates) for i in 1:model.stageNumber-1]: nothing
112112
(verbose > 0) && println("Initialize cuts")
113113

114114
# If computation of upper-bound is needed, a set of scenarios is built
@@ -143,7 +143,7 @@ function run_SDDP!(model::SPModel,
143143
####################
144144
# cut pruning
145145
if param.pruning[:pruning]
146-
prune_cuts!(model, param, V, stockTrajectories, territory, stats.niterations, verbose)
146+
prune_cuts!(model, param, V, stockTrajectories, activecuts, stats.niterations, verbose)
147147
if (stats.niterations%param.pruning[:period]==0)
148148
problems = hotstart_SDDP(model, param, V)
149149
end

src/cutpruning.jl

Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
66
#############################################################################
77

8-
type Territories
8+
type ActiveCutsContainer
99
ncuts::Int
1010
territories::Array{Array}
1111
nstates::Int
@@ -40,7 +40,7 @@ Exact pruning of all polyhedral functions in input array.
4040
Polyhedral functions where cuts will be removed
4141
* `trajectories::Array{Float64, 3}`
4242
Previous trajectories
43-
* `territory::Array{Territories}`
43+
* `territory::Array{ActiveCutsContainer}`
4444
Container storing the territory for each cuts
4545
* `it::Int64`:
4646
current iteration number
@@ -50,18 +50,18 @@ function prune_cuts!(model::SPModel,
5050
param::SDDPparameters,
5151
V::Vector{PolyhedralFunction},
5252
trajectories::Array{Float64, 3},
53-
territory::Union{Void, Array{Territories}},
53+
territory::Union{Void, Array{ActiveCutsContainer}},
5454
it::Int64,
5555
verbose::Int64)
5656
# Basic pruning: remove redundant cuts
5757
remove_redundant_cuts!(V)
5858

5959
# If pruning is performed with territory heuristic, update territory
6060
# at given iteration:
61-
if param.pruning[:type] ["territory", "mixed"]
61+
if param.pruning[:type] ["level1", "exact+"]
6262
for t in 1:model.stageNumber-1
6363
states = reshape(trajectories[t, :, :], param.forwardPassNumber, model.dimStates)
64-
find_territory!(territory[t], V[t], states)
64+
find_level1_cuts!(territory[t], V[t], states)
6565
end
6666
end
6767

@@ -74,13 +74,13 @@ function prune_cuts!(model::SPModel,
7474
for i in 1:length(V)-1
7575
if param.pruning[:type] == "exact"
7676
# apply exact cuts pruning:
77-
V[i] = exact_prune_cuts(model, param, V[i])
78-
elseif param.pruning[:type] == "territory"
77+
V[i] = exact_cuts_pruning(model, param, V[i])
78+
elseif param.pruning[:type] == "level1"
7979
# apply heuristic to prune cuts:
80-
V[i] = remove_empty_cuts!(territory[i], V[i])
81-
elseif param.pruning[:type] == "mixed"
80+
V[i] = level1_cuts_pruning!(territory[i], V[i])
81+
elseif param.pruning[:type] == "exact+"
8282
# apply mixed heuristic to prune cuts:
83-
V[i] = remove_cuts_usefulness!(model, territory[i], V[i], param.SOLVER)
83+
V[i] = exact_cuts_pruning_accelerated!(model, territory[i], V[i], param.SOLVER)
8484
end
8585
end
8686

@@ -104,7 +104,7 @@ Remove useless cuts in PolyhedralFunction.
104104
# Return
105105
* `PolyhedralFunction`: pruned polyhedral function
106106
"""
107-
function exact_prune_cuts(model::SPModel, params::SDDPparameters, V::PolyhedralFunction)
107+
function exact_cuts_pruning(model::SPModel, params::SDDPparameters, V::PolyhedralFunction)
108108
ncuts = V.numCuts
109109
# Find all active cuts:
110110
if ncuts > 1
@@ -157,102 +157,103 @@ end
157157
# Territory algorithm
158158
########################################
159159

160-
Territories(ndim) = Territories(0, [], 0, Array{Float64}(0, ndim))
160+
ActiveCutsContainer(ndim) = ActiveCutsContainer(0, [], 0, Array{Float64}(0, ndim))
161161

162162

163-
""" Update territories with cuts previously computed during backward pass. """
164-
function find_territory!(territory, V, states)
163+
"""Update territories with cuts previously computed during backward pass."""
164+
function find_level1_cuts!(cutscontainer, V, states)
165165
nc = V.numCuts
166166
# get number of new positions to analyse:
167167
nx = size(states, 1)
168-
nt = nc - territory.ncuts
168+
nt = nc - cutscontainer.ncuts
169169

170170
for i in 1:nt
171-
add_cut!(territory)
172-
update_territory!(territory, V, nc - nt + i)
171+
add_cut!(cutscontainer)
172+
update_territory!(cutscontainer, V, nc - nt + i)
173173
end
174174

175175
# ensure that territory has the same number of cuts as V!
176-
assert(territory.ncuts == V.numCuts)
176+
assert(cutscontainer.ncuts == V.numCuts)
177177

178178
for i in 1:nx
179179
x = collect(states[i, :])
180-
add_state!(territory, V, x)
180+
add_state!(cutscontainer, V, x)
181181
end
182-
183182
end
184183

185184

186185
"""Update territories considering new cut with index `indcut`."""
187-
function update_territory!(territory, V, indcut)
188-
for k in 1:territory.ncuts
186+
function update_territory!(cutscontainer, V, indcut)
187+
for k in 1:cutscontainer.ncuts
189188
if k == indcut
190189
continue
191190
end
192191
todelete = []
193-
for (num, (ix, cost)) in enumerate(territory.territories[k])
194-
x = collect(territory.states[ix, :])
192+
for (num, (ix, cost)) in enumerate(cutscontainer.territories[k])
193+
x = collect(cutscontainer.states[ix, :])
195194

196195
costnewcut = cutvalue(V, indcut, x)
197196

198197
if costnewcut > cost
199198
push!(todelete, num)
200-
push!(territory.territories[indcut], (ix, costnewcut))
199+
push!(cutscontainer.territories[indcut], (ix, costnewcut))
201200
end
202201
end
203-
deleteat!(territory.territories[k], todelete)
202+
deleteat!(cutscontainer.territories[k], todelete)
204203
end
205204
end
206205

207206

208207
"""Add cut to `territory`."""
209-
function add_cut!(territory)
210-
push!(territory.territories, [])
211-
territory.ncuts += 1
208+
function add_cut!(cutscontainer)
209+
push!(cutscontainer.territories, [])
210+
cutscontainer.ncuts += 1
212211
end
213212

214213

215214
"""Add a new state and update territories."""
216-
function add_state!(territory::Territories, V::PolyhedralFunction, x::Array{Float64})
215+
function add_state!(cutscontainer::ActiveCutsContainer, V::PolyhedralFunction, x::Array{Float64})
217216
# Get cut which is the supremum at point `x`:
218217
bcost, bcuts = optimalcut(x, V)
219218

220219
# Add `x` to the territory of cut `bcuts`:
221-
territory.nstates += 1
222-
push!(territory.territories[bcuts], (territory.nstates, bcost))
220+
cutscontainer.nstates += 1
221+
push!(cutscontainer.territories[bcuts], (cutscontainer.nstates, bcost))
223222

224223
# Add `x` to the list of visited state:
225-
territory.states = vcat(territory.states, x')
224+
cutscontainer.states = vcat(cutscontainer.states, x')
226225
end
227226

228227

229-
"""Remove empty cuts with heuristic in PolyhedralFunction."""
230-
function remove_empty_cuts!(territory::Territories, V::PolyhedralFunction)
231-
assert(territory.ncuts == V.numCuts)
228+
"""Remove inactive cuts in PolyhedralFunction with territory heuristic."""
229+
function level1_cuts_pruning!(cutscontainer::ActiveCutsContainer, V::PolyhedralFunction)
230+
assert(cutscontainer.ncuts == V.numCuts)
232231

233-
nstates = [length(terr) for terr in territory.territories]
232+
nstates = [length(terr) for terr in cutscontainer.territories]
234233
active_cuts = nstates .> 0
235234

236-
territory.territories = territory.territories[active_cuts]
237-
territory.ncuts = sum(active_cuts)
235+
cutscontainer.territories = cutscontainer.territories[active_cuts]
236+
cutscontainer.ncuts = sum(active_cuts)
238237
return PolyhedralFunction(V.betas[active_cuts],
239238
V.lambdas[active_cuts, :],
240239
sum(active_cuts))
241240
end
242241

243242

244243
"""Remove empty cuts in PolyhedralFunction with usefulness test."""
245-
function remove_cuts_usefulness!(model::SPModel, territory::Territories, V::PolyhedralFunction, solver)
246-
assert(territory.ncuts == V.numCuts)
244+
function exact_cuts_pruning_accelerated!(model::SPModel,
245+
cutscontainer::ActiveCutsContainer,
246+
V::PolyhedralFunction, solver)
247+
assert(cutscontainer.ncuts == V.numCuts)
247248

248-
nstates = [length(terr) for terr in territory.territories]
249+
nstates = [length(terr) for terr in cutscontainer.territories]
249250
# Set of inactive cuts:
250251
inactive_cuts = nstates .== 0
251252
# Set of active cuts:
252253
active_cuts = nstates .> 0
253254

254255
# get index of inactive cuts:
255-
index = collect(1:territory.ncuts)[inactive_cuts]
256+
index = collect(1:cutscontainer.ncuts)[inactive_cuts]
256257

257258
# Check if inactive cuts are useful or not:
258259
for id in index
@@ -263,15 +264,15 @@ function remove_cuts_usefulness!(model::SPModel, territory::Territories, V::Poly
263264
end
264265

265266
# Remove useless cuts:
266-
territory.territories = territory.territories[active_cuts]
267-
territory.ncuts = sum(active_cuts)
267+
cutscontainer.territories = cutscontainer.territories[active_cuts]
268+
cutscontainer.ncuts = sum(active_cuts)
268269
return PolyhedralFunction(V.betas[active_cuts],
269270
V.lambdas[active_cuts, :],
270271
sum(active_cuts))
271272
end
272273

273274

274-
"""Get cut which approximate the best value function at point `x`."""
275+
"""Find active cut at point `xf`."""
275276
function optimalcut(xf::Vector{Float64}, V::PolyhedralFunction)
276277
bestcost = -Inf::Float64
277278
bestcut = -1
@@ -293,7 +294,7 @@ end
293294

294295

295296
"""
296-
Get approximation of value function at given point `x`.
297+
Get value of cut with index `indc` at point `x`.
297298
298299
# Arguments
299300
- `V::PolyhedralFunction`

src/objects.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,8 @@ type SDDPparameters
171171
mipsolver=nothing,
172172
rho0=0., alpha=1.)
173173

174-
if ~(pruning_algo ["none", "mixed", "territory", "exact"])
175-
throw(ArgumentError("`pruning_algo` must be `none`, `mixed`, `territory`, `exact`"))
174+
if ~(pruning_algo ["none", "exact+", "level1", "exact"])
175+
throw(ArgumentError("`pruning_algo` must be `none`, `level1`, `exact` or `exact+`"))
176176
end
177177
is_acc = (rho0 > 0.)
178178
accparams = is_acc? Dict(:ρ0=>rho0, :alpha=>alpha, :rho=>rho0): Dict()

test/sddp.jl

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -118,15 +118,15 @@ facts("SDDP algorithm: 1D case") do
118118
# Check computation of optimal cut:
119119
@fact StochDynamicProgramming.optimalcut([0., 0.], vt)[2] --> 1
120120

121-
terr = StochDynamicProgramming.Territories(2)
122-
StochDynamicProgramming.find_territory!(terr, vt, [0. 0.; 1. 0.])
121+
terr = StochDynamicProgramming.ActiveCutsContainer(2)
122+
StochDynamicProgramming.find_level1_cuts!(terr, vt, [0. 0.; 1. 0.])
123123
@fact terr.ncuts --> 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.remove_empty_cuts!(terr, vt)
129+
vt2 = StochDynamicProgramming.level1_cuts_pruning!(terr, vt)
130130
@fact isa(vt2, StochDynamicProgramming.PolyhedralFunction) --> true
131131
@fact vt2.numCuts --> 1
132132
@fact vt2.betas[1] --> vt.betas[1]
@@ -145,20 +145,20 @@ facts("SDDP algorithm: 1D case") do
145145
prune_cuts=1,
146146
max_iterations=1)
147147
V1 = solve_SDDP(model, param1, 0)[1]
148-
param1 = StochDynamicProgramming.SDDPparameters(solver,
148+
param2 = StochDynamicProgramming.SDDPparameters(solver,
149149
passnumber=n_scenarios,
150150
gap=epsilon,
151-
pruning_algo="territory",
151+
pruning_algo="level1",
152152
prune_cuts=1,
153153
max_iterations=1)
154-
V2 = solve_SDDP(model, param1, 0)[1]
155-
param1 = StochDynamicProgramming.SDDPparameters(solver,
154+
V2 = solve_SDDP(model, param2, 0)[1]
155+
param3 = StochDynamicProgramming.SDDPparameters(solver,
156156
passnumber=n_scenarios,
157157
gap=epsilon,
158-
pruning_algo="mixed",
158+
pruning_algo="exact+",
159159
prune_cuts=1,
160160
max_iterations=1)
161-
V3 = solve_SDDP(model, param1, 0)[1]
161+
V3 = solve_SDDP(model, param3, 0)[1]
162162

163163
n1 = StochDynamicProgramming.get_total_number_cuts(V1)
164164
n2 = StochDynamicProgramming.get_total_number_cuts(V2)

0 commit comments

Comments
 (0)