Skip to content

Commit

Permalink
more docs
Browse files Browse the repository at this point in the history
  • Loading branch information
joaquimg committed May 13, 2023
1 parent 5ff1fc5 commit 571cf56
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 37 deletions.
36 changes: 18 additions & 18 deletions benchmarks/runbench.jl
Original file line number Diff line number Diff line change
Expand Up @@ -149,28 +149,28 @@ SOLVERS = [
#=
PrimalDual BIN 10
=#
# (()->QB(GLPK.Optimizer(tm_lim=MAX_TIME*1_000),lb=-10,ub=10), BilevelJuMP.StrongDualityEqualityMode(), "glpk_sd10"),
# (()->QB(Mosek.Optimizer(MIO_MAX_TIME=MAX_TIME*1.0,OPTIMIZER_MAX_TIME=MAX_TIME*1.0),lb=-10,ub=10), BilevelJuMP.StrongDualityEqualityMode(), "mosek_sd10"),
# (()->QB(Gurobi.Optimizer(TimeLimit=MAX_TIME*1),lb=-10,ub=10), BilevelJuMP.StrongDualityEqualityMode(), "gurobi_sd10"),
# (()->QB(cpx(),lb=-10,ub=10), BilevelJuMP.StrongDualityEqualityMode(), "cplex_sd10"),
# (()->QB(Xpress.Optimizer(MAXTIME=-MAX_TIME*1),lb=-10,ub=10), BilevelJuMP.StrongDualityEqualityMode(), "xpress_sd10"),
# (()->QB(cache(Cbc.Optimizer(seconds=MAX_TIME*1.0)),lb=-10,ub=10), BilevelJuMP.StrongDualityEqualityMode(), "cbc_sd10"), #TODO
# (()->QB(SCIP.Optimizer(limits_time=MAX_TIME*1),lb=-10,ub=10), BilevelJuMP.StrongDualityEqualityMode(), "scip_sd10"),
# (()->QB(GLPK.Optimizer(tm_lim=MAX_TIME*1_000),lb=-10,ub=10), BilevelJuMP.StrongDualityMode(), "glpk_sd10"),
# (()->QB(Mosek.Optimizer(MIO_MAX_TIME=MAX_TIME*1.0,OPTIMIZER_MAX_TIME=MAX_TIME*1.0),lb=-10,ub=10), BilevelJuMP.StrongDualityMode(), "mosek_sd10"),
# (()->QB(Gurobi.Optimizer(TimeLimit=MAX_TIME*1),lb=-10,ub=10), BilevelJuMP.StrongDualityMode(), "gurobi_sd10"),
# (()->QB(cpx(),lb=-10,ub=10), BilevelJuMP.StrongDualityMode(), "cplex_sd10"),
# (()->QB(Xpress.Optimizer(MAXTIME=-MAX_TIME*1),lb=-10,ub=10), BilevelJuMP.StrongDualityMode(), "xpress_sd10"),
# (()->QB(cache(Cbc.Optimizer(seconds=MAX_TIME*1.0)),lb=-10,ub=10), BilevelJuMP.StrongDualityMode(), "cbc_sd10"), #TODO
# (()->QB(SCIP.Optimizer(limits_time=MAX_TIME*1),lb=-10,ub=10), BilevelJuMP.StrongDualityMode(), "scip_sd10"),
#=
PrimalDual BIN 100
=#
# (()->QB(GLPK.Optimizer(tm_lim=MAX_TIME*1_000),lb=-100,ub=100), BilevelJuMP.StrongDualityEqualityMode(), "glpk_sd100"),
# (()->QB(Mosek.Optimizer(MIO_MAX_TIME=MAX_TIME*1.0,OPTIMIZER_MAX_TIME=MAX_TIME*1.0),lb=-100,ub=100), BilevelJuMP.StrongDualityEqualityMode(), "mosek_sd100"),
# (()->QB(Gurobi.Optimizer(TimeLimit=MAX_TIME*1),lb=-100,ub=100), BilevelJuMP.StrongDualityEqualityMode(), "gurobi_sd100"),
# (()->QB(cpx(),lb=-100,ub=100), BilevelJuMP.StrongDualityEqualityMode(), "cplex_sd100"),
# (()->QB(Xpress.Optimizer(MAXTIME=-MAX_TIME*1),lb=-100,ub=100), BilevelJuMP.StrongDualityEqualityMode(), "xpress_sd100"),
# (()->QB(cache(Cbc.Optimizer(seconds=MAX_TIME*1.0)),lb=-100,ub=100), BilevelJuMP.StrongDualityEqualityMode(), "cbc_sd100"),
# (()->QB(SCIP.Optimizer(limits_time=MAX_TIME*1),lb=-100,ub=100), BilevelJuMP.StrongDualityEqualityMode(), "scip_sd100"),
# (()->QB(GLPK.Optimizer(tm_lim=MAX_TIME*1_000),lb=-100,ub=100), BilevelJuMP.StrongDualityMode(), "glpk_sd100"),
# (()->QB(Mosek.Optimizer(MIO_MAX_TIME=MAX_TIME*1.0,OPTIMIZER_MAX_TIME=MAX_TIME*1.0),lb=-100,ub=100), BilevelJuMP.StrongDualityMode(), "mosek_sd100"),
# (()->QB(Gurobi.Optimizer(TimeLimit=MAX_TIME*1),lb=-100,ub=100), BilevelJuMP.StrongDualityMode(), "gurobi_sd100"),
# (()->QB(cpx(),lb=-100,ub=100), BilevelJuMP.StrongDualityMode(), "cplex_sd100"),
# (()->QB(Xpress.Optimizer(MAXTIME=-MAX_TIME*1),lb=-100,ub=100), BilevelJuMP.StrongDualityMode(), "xpress_sd100"),
# (()->QB(cache(Cbc.Optimizer(seconds=MAX_TIME*1.0)),lb=-100,ub=100), BilevelJuMP.StrongDualityMode(), "cbc_sd100"),
# (()->QB(SCIP.Optimizer(limits_time=MAX_TIME*1),lb=-100,ub=100), BilevelJuMP.StrongDualityMode(), "scip_sd100"),
#=
PrimalDual NLP (DONE)
=#
# (with_att(Ipopt.Optimizer, "max_cpu_time" => MAX_TIME*1.0), BilevelJuMP.StrongDualityEqualityMode(), "ipopt_sd"),
# (new_knitro, BilevelJuMP.StrongDualityEqualityMode(), "knitro_sd"),
# (with_att(Ipopt.Optimizer, "max_cpu_time" => MAX_TIME*1.0), BilevelJuMP.StrongDualityMode(), "ipopt_sd"),
# (new_knitro, BilevelJuMP.StrongDualityMode(), "knitro_sd"),
#=
Product NLP (DONE)
=#
Expand All @@ -185,8 +185,8 @@ SOLVERS = [
=#
# (() -> AmplNLWriter.Optimizer("bonmin"), BilevelJuMP.ProductMode(1e-7), "bonmin_prod"),
# (() -> AmplNLWriter.Optimizer("couenne"), BilevelJuMP.ProductMode(1e-7), "couenne_prod"),
# (() -> AmplNLWriter.Optimizer("bonmin"), BilevelJuMP.StrongDualityEqualityMode(), "bonmin_sd"),
# (() -> AmplNLWriter.Optimizer("couenne"), BilevelJuMP.StrongDualityEqualityMode(), "couenne_sd"),
# (() -> AmplNLWriter.Optimizer("bonmin"), BilevelJuMP.StrongDualityMode(), "bonmin_sd"),
# (() -> AmplNLWriter.Optimizer("couenne"), BilevelJuMP.StrongDualityMode(), "couenne_sd"),
]

PROBLEMS = [:SVR, :TOLL, :FORECAST, :RAND]
Expand Down
21 changes: 14 additions & 7 deletions docs/src/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,19 @@ LowerOnly
## Enums

```@docs
Level
LOWER_BOTH
UPPER_BOTH
LOWER_ONLY
UPPER_ONLY
DUAL_OF_LOWER
BilevelJuMP.Level
BilevelJuMP.LOWER_BOTH
BilevelJuMP.UPPER_BOTH
BilevelJuMP.LOWER_ONLY
BilevelJuMP.UPPER_ONLY
BilevelJuMP.DUAL_OF_LOWER
```

```@docs
BilevelJuMP.IndicatorSetting
BilevelJuMP.ZERO_ONE
BilevelJuMP.ZERO_ZERO
BilevelJuMP.ONE_ZERO
```

## Structs
Expand All @@ -50,7 +57,7 @@ BilevelJuMP.SOS1Mode
BilevelJuMP.FortunyAmatMcCarlMode
BilevelJuMP.IndicatorMode
BilevelJuMP.ProductMode
BilevelJuMP.StrongDualityEqualityMode
BilevelJuMP.StrongDualityMode
BilevelJuMP.ComplementMode
BilevelJuMP.MixedMode
```
Expand Down
45 changes: 44 additions & 1 deletion src/jump.jl
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,12 @@ function BilevelModel(
JuMP.set_optimizer(bm, optimizer_constructor; add_bridges = add_bridges)
return bm
end

"""
set_mode(bm::BilevelModel, mode::AbstractBilevelSolverMode)
Set the mode of a bilevel model.
"""
function set_mode(bm::BilevelModel, mode::AbstractBilevelSolverMode)
bm.mode = deepcopy(mode)
reset!(bm.mode)
Expand Down Expand Up @@ -961,6 +967,12 @@ function check_mixed_mode(mode)
"Cant set/get mode on a specific object because the base mode is $mode while it should be MixedMode in this case. Run `set_mode(model, BilevelJuMP.MixedMode())`",
)
end

"""
set_mode(ci::BilevelVariableRef, mode::AbstractBilevelSolverMode)
Set the mode of a constraint. This is used in `MixedMode` reformulations.
"""
function set_mode(
ci::BilevelConstraintRef,
mode::AbstractBilevelSolverMode{T},
Expand All @@ -973,6 +985,13 @@ function set_mode(
bm.mode.constraint_mode_map_c[ctr] = _mode
return nothing
end

"""
unset_mode(ci::BilevelConstraintRef)
Unset the mode of a constraint. This will use the default mode for the constraint.
This is used in `MixedMode` reformulations.
"""
function unset_mode(ci::BilevelConstraintRef)
bm = ci.model
check_mixed_mode(bm.mode)
Expand All @@ -981,6 +1000,11 @@ function unset_mode(ci::BilevelConstraintRef)
return nothing
end

"""
get_mode(ci::BilevelConstraintRef)
Get the mode of a constraint. This is used in `MixedMode` reformulations.
"""
function get_mode(ci::BilevelConstraintRef)
bm = ci.model
check_mixed_mode(bm.mode)
Expand All @@ -999,7 +1023,12 @@ function set_mode(::BilevelConstraintRef, ::StrongDualityMode{T}) where {T}
return error("Cant set StrongDualityMode in a specific constraint")
end

# mode for variable bounds
"""
set_mode(vi::BilevelVariableRef, mode::AbstractBilevelSolverMode)
Set the mode of the bounds of a variable.
This is used in `MixedMode` reformulations.
"""
function set_mode(
vi::BilevelVariableRef,
mode::AbstractBilevelSolverMode{T},
Expand All @@ -1013,6 +1042,14 @@ function set_mode(
bm.mode.constraint_mode_map_v[var] = _mode
return nothing
end

"""
unset_mode(vi::BilevelVariableRef)
Unset the mode of the bounds of a variable.
This will use the default mode for the bounds.
This is used in `MixedMode` reformulations.
"""
function unset_mode(vi::BilevelVariableRef)
bm = vi.model
check_mixed_mode(bm.mode)
Expand All @@ -1021,6 +1058,12 @@ function unset_mode(vi::BilevelVariableRef)
return nothing
end

"""
get_mode(vi::BilevelVariableRef)
Get the mode of the bounds of a variable.
This is used in `MixedMode` reformulations.
"""
function get_mode(vi::BilevelVariableRef)
bm = vi.model
check_mixed_mode(bm.mode)
Expand Down
41 changes: 41 additions & 0 deletions src/jump_attributes.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
function JuMP.solve_time(bm::BilevelModel)
return bm.solve_time
end

"""
build_time(model::BilevelModel)
Return the time it took to build the model.
"""
function build_time(bm::BilevelModel)
return bm.build_time
end
Expand Down Expand Up @@ -116,25 +122,60 @@ function JuMP.result_count(bm::BilevelModel)::Int
return MOI.get(bm.solver, MOI.ResultCount())
end

"""
set_copy_names(model::BilevelModel)
Set the `copy_names` attribute of the solver to `true`.
"""
function set_copy_names(bm::BilevelModel)
bm.copy_names = true
return nothing
end

"""
unset_copy_names(model::BilevelModel)
Set the `copy_names` attribute of the solver to `false`.
"""
function unset_copy_names(bm::BilevelModel)
bm.copy_names = false
return nothing
end

"""
get_copy_names(model::BilevelModel)
Return the value of the `copy_names` attribute of the solver.
"""
function get_copy_names(bm::BilevelModel)
return bm.copy_names
end

"""
set_pass_start(model::BilevelModel)
Activate passing start values (both primal and dual) to the solver.
"""
function set_pass_start(bm::BilevelModel)
bm.pass_start = true
return nothing
end

"""
unset_pass_start(model::BilevelModel)
Deactivate passing start values (both primal and dual) to the solver.
"""
function unset_pass_start(bm::BilevelModel)
bm.pass_start = false
return nothing
end

"""
get_pass_start(model::BilevelModel)
Checks if passing start values (both primal and dual) to the solver is activated.
"""
function get_pass_start(bm::BilevelModel)
return bm.pass_start
end
27 changes: 17 additions & 10 deletions src/jump_objective.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,16 @@ function JuMP.objective_sense(m::InnerBilevelModel)
end
function JuMP.objective_function_type(m::InnerBilevelModel)
tp = JuMP.objective_function_type(mylevel_model(m))
return bilevel_type(m, tp)
return _bilevel_type(m, tp)
end
bilevel_type(::InnerBilevelModel, ::Type{JuMP.VariableRef}) = BilevelVariableRef
function bilevel_type(
_bilevel_type(::InnerBilevelModel, ::Type{JuMP.VariableRef}) = BilevelVariableRef
function _bilevel_type(
::InnerBilevelModel,
::Type{JuMP.GenericAffExpr{C,V}},
) where {C,V}
return JuMP.GenericAffExpr{C,BilevelVariableRef}
end
function bilevel_type(
function _bilevel_type(
::InnerBilevelModel,
::Type{JuMP.GenericQuadExpr{C,V}},
) where {C,V}
Expand Down Expand Up @@ -77,16 +77,16 @@ function JuMP.set_objective(
sense::MOI.OptimizationSense,
f::JuMP.AbstractJuMPScalar,
)
return bilevel_obj_error()
return _bilevel_obj_error()
end
JuMP.objective_sense(m::BilevelModel) = JuMP.objective_sense(m.upper)# bilevel_obj_error()
JuMP.objective_function_type(model::BilevelModel) = bilevel_obj_error()
JuMP.objective_function(model::BilevelModel) = bilevel_obj_error()
JuMP.objective_sense(m::BilevelModel) = JuMP.objective_sense(m.upper)# _bilevel_obj_error()
JuMP.objective_function_type(model::BilevelModel) = _bilevel_obj_error()
JuMP.objective_function(model::BilevelModel) = _bilevel_obj_error()
function JuMP.objective_function(model::BilevelModel, FT::Type)
return bilevel_obj_error()
return _bilevel_obj_error()
end

function bilevel_obj_error()
function _bilevel_obj_error()
return error(
"There is no objective for BilevelModel use Upper(.) and Lower(.)",
)
Expand All @@ -96,13 +96,20 @@ function JuMP.objective_value(model::BilevelModel)
_check_solver(model)
return MOI.get(model.solver, MOI.ObjectiveValue())
end

function JuMP.objective_value(model::UpperModel)
return JuMP.objective_value(model.m)
end

function JuMP.objective_value(model::LowerModel)
return lower_objective_value(model.m)
end

"""
lower_objective_value(model::BilevelModel; result::Int = 1)
Return the value of the objective function of the lower level problem.
"""
function lower_objective_value(model::BilevelModel; result::Int = 1)
f = JuMP.objective_function(Lower(model))
# Evaluate the lower objective expression
Expand Down
2 changes: 1 addition & 1 deletion src/modes/indicator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ The type of indicator function to use in the `IndicatorMode` mode.
)

"""
IndicatorMode(method::IndicatorSetting = ONE_ONE)
IndicatorMode(method::IndicatorSetting = BilevelJuMP.ONE_ONE)
Used to solve a bilevel problem with the
MPEC reformulation using indicator constaints to convert complementarity
Expand Down

0 comments on commit 571cf56

Please sign in to comment.