Skip to content

Commit 76ae060

Browse files
committed
[DOC] Add documentation and modify naming
1 parent 307d1d1 commit 76ae060

File tree

1 file changed

+94
-33
lines changed

1 file changed

+94
-33
lines changed

src/cutpruning.jl

Lines changed: 94 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,33 @@
77

88
type ActiveCutsContainer
99
ncuts::Int
10-
territories::Array{Array}
10+
territories::Array{Array} #set of states where cut k is active
1111
nstates::Int
12-
states::Array{Float64, 2}
12+
states::Array{Float64, 2} #set of states where cuts are tested
1313
end
1414

1515

16-
""" Remove redundant cuts in Polyhedral Value function `V`"""
17-
function remove_cuts(V::PolyhedralFunction)
16+
""" Remove redundant cuts in Polyhedral Value function `V`
17+
18+
# Arguments
19+
* `V::PolyhedralFunction`:
20+
"""
21+
function remove_cuts!(V::PolyhedralFunction)
1822
Vf = hcat(V.lambdas, V.betas)
1923
Vf = unique(Vf, 1)
2024
return PolyhedralFunction(Vf[:, end], Vf[:, 1:end-1], size(Vf)[1])
2125
end
2226

2327

24-
""" Remove redundant cuts in a vector of Polyhedral Functions `Vts`."""
28+
""" Remove redundant cuts in a vector of Polyhedral Functions `Vts`.
29+
30+
# Arguments
31+
* `Vts::Vector{PolyhedralFunction}`:
32+
"""
2533
function remove_redundant_cuts!(Vts::Vector{PolyhedralFunction})
2634
n_functions = length(Vts)-1
2735
for i in 1:n_functions
28-
Vts[i] = remove_cuts(Vts[i])
36+
Vts[i] = remove_cuts!(Vts[i])
2937
end
3038
end
3139

@@ -35,13 +43,14 @@ Exact pruning of all polyhedral functions in input array.
3543
3644
# Arguments
3745
* `model::SPModel`:
38-
* `params::SDDPparameters`:
46+
* `param::SDDPparameters`:
3947
* `Vector{PolyhedralFunction}`:
4048
Polyhedral functions where cuts will be removed
4149
* `trajectories::Array{Float64, 3}`
4250
Previous trajectories
4351
* `territory::Array{ActiveCutsContainer}`
44-
Container storing the territory for each cuts
52+
Container storing the territory (i.e. the set of tested states where
53+
a given cut is active) for each cuts
4554
* `it::Int64`:
4655
current iteration number
4756
* `verbose::Int64`
@@ -79,15 +88,15 @@ function prune_cuts!(model::SPModel,
7988
# apply heuristic to prune cuts:
8089
V[i] = level1_cuts_pruning!(territory[i], V[i])
8190
elseif param.pruning[:type] == "exact+"
82-
# apply mixed heuristic to prune cuts:
91+
# apply heuristicly accelerated exact pruning:
8392
V[i] = exact_cuts_pruning_accelerated!(model, territory[i], V[i], param.SOLVER)
8493
end
8594
end
8695

8796
# final number of cuts:
8897
ncuts_final = get_total_number_cuts(V)
8998

90-
(verbose > 0) && @printf(" Deflation: %.3f \n", ncuts_final/ncuts_initial)
99+
(verbose > 0) && @printf(" New cuts/Old cuts ratio: %.3f \n", ncuts_final/ncuts_initial)
91100
end
92101
end
93102

@@ -97,18 +106,18 @@ Remove useless cuts in PolyhedralFunction.
97106
98107
# Arguments
99108
* `model::SPModel`:
100-
* `params::SDDPparameters`:
109+
* `param::SDDPparameters`:
101110
* `V::PolyhedralFunction`:
102111
Polyhedral function where cuts will be removed
103112
104113
# Return
105114
* `PolyhedralFunction`: pruned polyhedral function
106115
"""
107-
function exact_cuts_pruning(model::SPModel, params::SDDPparameters, V::PolyhedralFunction)
116+
function exact_cuts_pruning(model::SPModel, param::SDDPparameters, V::PolyhedralFunction)
108117
ncuts = V.numCuts
109118
# Find all active cuts:
110119
if ncuts > 1
111-
active_cuts = Bool[is_cut_relevant(model, i, V, params.SOLVER)[1] for i=1:ncuts]
120+
active_cuts = Bool[is_cut_relevant(model, i, V, param.SOLVER)[1] for i=1:ncuts]
112121
return PolyhedralFunction(V.betas[active_cuts], V.lambdas[active_cuts, :], sum(active_cuts))
113122
else
114123
return V
@@ -160,20 +169,29 @@ end
160169
ActiveCutsContainer(ndim) = ActiveCutsContainer(0, [], 0, Array{Float64}(0, ndim))
161170

162171

163-
"""Update territories with cuts previously computed during backward pass."""
164-
function find_level1_cuts!(cutscontainer, V, states)
172+
"""Update territories (i.e. the set of tested states where
173+
a given cut is active) with cuts previously computed during backward pass.
174+
175+
# Arguments
176+
* `cutscontainer::ActiveCutsContainer`:
177+
* `Vt::PolyhedralFunction`:
178+
Object storing all cuts
179+
* `states`:
180+
Object storing all visited states
181+
"""
182+
function find_level1_cuts!(cutscontainer::ActiveCutsContainer, V::PolyhedralFunction, states)
165183
nc = V.numCuts
166184
# get number of new positions to analyse:
167185
nx = size(states, 1)
168-
nt = nc - cutscontainer.ncuts
186+
nt = nc - cutscontainer.numCuts
169187

170188
for i in 1:nt
171189
add_cut!(cutscontainer)
172190
update_territory!(cutscontainer, V, nc - nt + i)
173191
end
174192

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

178196
for i in 1:nx
179197
x = collect(states[i, :])
@@ -182,9 +200,18 @@ function find_level1_cuts!(cutscontainer, V, states)
182200
end
183201

184202

185-
"""Update territories considering new cut with index `indcut`."""
186-
function update_territory!(cutscontainer, V, indcut)
187-
for k in 1:cutscontainer.ncuts
203+
"""Update territories (i.e. the set of tested states where
204+
a given cut is active) considering new cut given by index `indcut`.
205+
206+
# Arguments
207+
* `cutscontainer::ActiveCutsContainer`:
208+
* `V::PolyhedralFunction`:
209+
Object storing all cuts
210+
* `indcut::Int64`:
211+
new cut index
212+
"""
213+
function update_territory!(cutscontainer::ActiveCutsContainer, V::PolyhedralFunction, indcut::Int64)
214+
for k in 1:cutscontainer.numCuts
188215
if k == indcut
189216
continue
190217
end
@@ -204,16 +231,16 @@ function update_territory!(cutscontainer, V, indcut)
204231
end
205232

206233

207-
"""Add cut to `territory`."""
208-
function add_cut!(cutscontainer)
234+
"""Add cut to `ActiveCutsContainer`."""
235+
function add_cut!(cutscontainer::ActiveCutsContainer)
209236
push!(cutscontainer.territories, [])
210-
cutscontainer.ncuts += 1
237+
cutscontainer.numCuts += 1
211238
end
212239

213240

214-
"""Add a new state and update territories."""
241+
"""Add a new state to test and accordingly update territories of each cut."""
215242
function add_state!(cutscontainer::ActiveCutsContainer, V::PolyhedralFunction, x::Array{Float64})
216-
# Get cut which is the supremum at point `x`:
243+
# Get cut which is active at point `x`:
217244
bcost, bcuts = optimalcut(x, V)
218245

219246
# Add `x` to the territory of cut `bcuts`:
@@ -225,26 +252,48 @@ function add_state!(cutscontainer::ActiveCutsContainer, V::PolyhedralFunction, x
225252
end
226253

227254

228-
"""Remove inactive cuts in PolyhedralFunction with territory heuristic."""
255+
"""Remove cuts in PolyhedralFunction that are inactive on all visited states.
256+
# Arguments
257+
* `cutscontainer::ActiveCutsContainer`:
258+
* `V::PolyhedralFunction`:
259+
Object storing all cuts
260+
# Return
261+
* `V::PolyhedralFunction`
262+
the new PolyhedralFunction
263+
"""
229264
function level1_cuts_pruning!(cutscontainer::ActiveCutsContainer, V::PolyhedralFunction)
230-
assert(cutscontainer.ncuts == V.numCuts)
265+
assert(cutscontainer.numCuts == V.numCuts)
231266

232267
nstates = [length(terr) for terr in cutscontainer.territories]
233268
active_cuts = nstates .> 0
234269

235270
cutscontainer.territories = cutscontainer.territories[active_cuts]
236-
cutscontainer.ncuts = sum(active_cuts)
271+
cutscontainer.numCuts = sum(active_cuts)
237272
return PolyhedralFunction(V.betas[active_cuts],
238273
V.lambdas[active_cuts, :],
239274
sum(active_cuts))
240275
end
241276

242277

243-
"""Remove empty cuts in PolyhedralFunction with usefulness test."""
278+
"""Remove useless cuts in PolyhedralFunction
279+
280+
First test if cuts are active on the visited states,
281+
then test remaining cuts.
282+
283+
# Arguments
284+
* `model::SPModel`:
285+
* `cutscontainer::ActiveCutsContainer`:
286+
* `V::PolyhedralFunction`:
287+
Object storing all cuts
288+
289+
# Return
290+
* `V::PolyhedralFunction`
291+
the new PolyhedralFunction
292+
"""
244293
function exact_cuts_pruning_accelerated!(model::SPModel,
245294
cutscontainer::ActiveCutsContainer,
246295
V::PolyhedralFunction, solver)
247-
assert(cutscontainer.ncuts == V.numCuts)
296+
assert(cutscontainer.numCuts == V.numCuts)
248297

249298
nstates = [length(terr) for terr in cutscontainer.territories]
250299
# Set of inactive cuts:
@@ -253,7 +302,7 @@ function exact_cuts_pruning_accelerated!(model::SPModel,
253302
active_cuts = nstates .> 0
254303

255304
# get index of inactive cuts:
256-
index = collect(1:cutscontainer.ncuts)[inactive_cuts]
305+
index = collect(1:cutscontainer.numCuts)[inactive_cuts]
257306

258307
# Check if inactive cuts are useful or not:
259308
for id in index
@@ -265,14 +314,26 @@ function exact_cuts_pruning_accelerated!(model::SPModel,
265314

266315
# Remove useless cuts:
267316
cutscontainer.territories = cutscontainer.territories[active_cuts]
268-
cutscontainer.ncuts = sum(active_cuts)
317+
cutscontainer.numCuts = sum(active_cuts)
269318
return PolyhedralFunction(V.betas[active_cuts],
270319
V.lambdas[active_cuts, :],
271320
sum(active_cuts))
272321
end
273322

274323

275-
"""Find active cut at point `xf`."""
324+
"""Find active cut at point `xf`.
325+
326+
# Arguments
327+
* `xf::Vector{Float64}`:
328+
* `V::PolyhedralFunction`:
329+
Object storing all cuts
330+
331+
# Return
332+
`bestcost::Float64`
333+
Value of maximal cut at point `xf`
334+
`bestcut::Int64`
335+
Index of maximal cut at point `xf`
336+
"""
276337
function optimalcut(xf::Vector{Float64}, V::PolyhedralFunction)
277338
bestcost = -Inf::Float64
278339
bestcut = -1

0 commit comments

Comments
 (0)