Currently the doc of JuMP teaches people how to modify constraints and how to modify objective_expression. In my mind, there is a more natural way:
- Build an initial model (that we will revise later) partly involving some “provisional” expressions
- Build some “provisional” constraints and “provisional” objective with the “provisional” expressions built in step 1. (may need to memorize a dependency graph)
optimize!(model)
(work with the model in current status)- Revise the “provisional” expressions defined in step 1.
- (maybe) execute a command
update!(model)
, during which the dependent “provisional” constraints and “provisional” objective_expression are updated (according to the dependency graph). optimize!(model)
(work with the revised model)- goto step 4
The code is like
julia> using JuMP
julia> model = JuMP.Model();
julia> @variable(model, x[1:3]);
julia> expr = @expression(model, x[2] + 2x[1])
x[2] + 2 x[1]
julia> @constraint(model, cons, x[1] + x[3] + expr == 7)
cons : 3 x[1] + x[2] + x[3] == 7
julia> @objective(model, Min, x[2] - 2x[3] - expr)
0 x[2] - 2 x[3] - 2 x[1]
julia> print(model) # the provisional model
Min -2 x[3] - 2 x[1]
Subject to
cons : 3 x[1] + x[2] + x[3] == 7
julia> quote JuMP.set_expression_coefficient(expr, x[1], 3) end; # execute this code (Step 4 above), then we can observe the follows
julia> # expr = x[2] + 3 x[1]
julia> quote JuMP.update!(model) end; # execute this code, then we can observe the follows
julia> # cons : x[1] + x[3] + (x[2] + 3x[1]) == 7
julia> # objective_expression : x[2] - 2x[3] - (x[2] + 3 x[1])
I don’t know whether this is proper.
Under the existing JuMP API, I would equivalently write the above procedure—from a complementary perspective, as
julia> using JuMP
julia> begin
model = JuMP.Model();
@variable(model, x[1:3]);
# pre-prepare the following 3 expressions to save time
@expression(model, cons_lhs_1, x[1] + x[3])
@expression(model, cons_rhs, 7)
@expression(model, obj_expr_1, x[2] - 2x[3])
@constraint(model, cons, 0 == 1) # an initial dumb one
end;
julia> function modify!(model, c_x1, c_x2)
JuMP.delete(model, model[:cons])
expr = @expression(model, model[:x][1]c_x1 + model[:x][2]c_x2)
model[:cons] = @constraint(model, model[:cons_lhs_1] + expr == model[:cons_rhs])
@objective(model, Min, model[:obj_expr_1] - expr)
return nothing
end;
julia> modify!(model, 3, 1)
julia> print(model)
Min -2 x[3] - 3 x[1]
Subject to
4 x[1] + x[2] + x[3] == 7
julia> modify!(model, 5, 2)
julia> print(model)
Min -x[2] - 2 x[3] - 5 x[1]
Subject to
6 x[1] + 2 x[2] + x[3] == 7
julia> cons != model[:cons] && (cons = model[:cons]);