Originally Contributed by: Arpit Bhatia
This tutorial deals with how to modify models after they have been created and solved. This functionality can be useful, for example, when we are solving many similar models in succession or generating the model dynamically. Additionally it is sometimes desirable for the solver to re-start from the last solution to reduce running times for successive solves (“hot-start”).
using JuMP
model = Model()
@variable(model, x);
The set_lower_bound
and set_upper_bound
functions can be used to create as well as modify an existing variable bound.
set_lower_bound(x, 3)
lower_bound(x)
3.0
set_lower_bound(x, 2)
lower_bound(x)
2.0
We can delete variable bounds using the delete_lower_bound
and delete_upper_bound
functions.
delete_lower_bound(x)
has_lower_bound(x)
false
We can assign a fixed value to a variable using fix
.
fix(x, 5)
fix_value(x)
5.0
However, fixing a variable with existing bounds will throw an error.
@variable(model, y >= 0);
fix(y, 2)
Unable to fix y to 2 because it has existing variable bounds. Consider calling `JuMP.fix(variable, value; force=true)` which will delete existing bounds before fixing the variable. Stacktrace: [1] error(::String) at ./error.jl:33 [2] _moi_fix(::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.AbstractOptimizer,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}, ::VariableRef, ::Int64, ::Bool) at /home/mbesancon/.julia/packages/JuMP/e0Uc2/src/variables.jl:553 [3] fix(::VariableRef, ::Int64; force::Bool) at /home/mbesancon/.julia/packages/JuMP/e0Uc2/src/variables.jl:541 [4] fix(::VariableRef, ::Int64) at /home/mbesancon/.julia/packages/JuMP/e0Uc2/src/variables.jl:541 [5] top-level scope at In[8]:1 [6] include_string(::Function, ::Module, ::String, ::String) at ./loading.jl:1091 [7] execute_code(::String, ::String) at /home/mbesancon/.julia/packages/IJulia/a1SNk/src/execute_request.jl:27 [8] execute_request(::ZMQ.Socket, ::IJulia.Msg) at /home/mbesancon/.julia/packages/IJulia/a1SNk/src/execute_request.jl:86 [9] #invokelatest#1 at ./essentials.jl:710 [inlined] [10] invokelatest at ./essentials.jl:709 [inlined] [11] eventloop(::ZMQ.Socket) at /home/mbesancon/.julia/packages/IJulia/a1SNk/src/eventloop.jl:8 [12] (::IJulia.var"#15#18")() at ./task.jl:356
As we can see in the error message above, we have to specify to JuMP that we wish to forcefuly remove the bound.
fix(y, 2; force = true)
fix_value(y)
2.0
We can also call the unfix
function to remove the fixed value.
unfix(x)
is_fixed(x)
false
The all_variables
function returns a list of all variables present in the model.
all_variables(model)
2-element Array{VariableRef,1}: x y
To delete variables from a model, we can use the delete
function.
delete(model, x)
all_variables(model)
1-element Array{VariableRef,1}: y
We can also check whether a variable is a valid JuMP variable in a model using the is_valid
function.
is_valid(model, x)
false
model = Model()
@variable(model, x);
It is also possible to modify the scalar coefficients (but notably not yet the quadratic coefficients) using the set_normalized_coefficient
function.
@constraint(model, con, 2x <= 1);
set_normalized_coefficient(con, x, 3)
con
Just like for deleting variables, we can use the delete
function for constraints as well.
delete(model, con)
is_valid(model, con)
false
model = Model()
@variable(model, x)
@objective(model, Min, 7x + 4);
The function objective_function
is used to query the objective of a model.
objective_function(model)
objective_sense
is similarily used to query the objective sense of a model.
objective_sense(model)
MIN_SENSE::OptimizationSense = 0
To easiest way to change the objective is to simply call @objective
again
@objective(model, Max, 8x + 3)
objective_function(model)
objective_sense(model)
MAX_SENSE::OptimizationSense = 1
Another way is to change the objective is to use the low-level functions set_objective_function
and set_objective_sense
.
set_objective_function(model, 5x + 11)
objective_function(model)
set_objective_sense(model, MOI.MIN_SENSE)
objective_sense(model)
MIN_SENSE::OptimizationSense = 0
Note that we can't use the Min and Max shortcuts here as set_objective_sense
is a low level function.