Problem modification

In addition to adding and deleting constraints and variables, MathOptInterface supports modifying, in-place, coefficients in the constraints and the objective function of a model.

These modifications can be grouped into two categories:

  • modifications which replace the set of function of a constraint with a new set or function
  • modifications which change, in-place, a component of a function
Warning

Some ModelLike objects do not support problem modification.

Modify the set of a constraint

Use set and ConstraintSet to modify the set of a constraint by replacing it with a new instance of the same type.

julia> c = MOI.add_constraint(           model,           MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, x)], 0.0),           MOI.EqualTo(1.0),       )MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.EqualTo{Float64}}(1)julia> MOI.set(model, MOI.ConstraintSet(), c, MOI.EqualTo(2.0));julia> MOI.get(model, MOI.ConstraintSet(), c) == MOI.EqualTo(2.0)true

However, the following will fail as the new set is of a different type to the original set:

julia> MOI.set(model, MOI.ConstraintSet(), c, MOI.GreaterThan(2.0))ERROR: [...]

Special cases: set transforms

If our constraint is an affine inequality, then this corresponds to modifying the right-hand side of a constraint in linear programming.

In some special cases, solvers may support efficiently changing the set of a constraint (for example, from LessThan to GreaterThan). For these cases, MathOptInterface provides the transform method.

The transform function returns a new constraint index, and the old constraint index (that is, c) is no longer valid.

julia> c = MOI.add_constraint(           model,           MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, x)], 0.0),           MOI.LessThan(1.0),       )MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.LessThan{Float64}}(1)julia> new_c = MOI.transform(model, c, MOI.GreaterThan(2.0));julia> MOI.is_valid(model, c)falsejulia> MOI.is_valid(model, new_c)true
Note

transform cannot be called with a set of the same type. Use set instead.

Modify the function of a constraint

Use set and ConstraintFunction to modify the function of a constraint by replacing it with a new instance of the same type.

julia> c = MOI.add_constraint(           model,           MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, x)], 0.0),           MOI.EqualTo(1.0),       )MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.EqualTo{Float64}}(1)julia> new_f = MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(2.0, x)], 1.0);julia> MOI.set(model, MOI.ConstraintFunction(), c, new_f);julia> MOI.get(model, MOI.ConstraintFunction(), c)  new_ftrue

However, the following will fail as the new function is of a different type to the original function:

julia> MOI.set(model, MOI.ConstraintFunction(), c, x)ERROR: [...]

Modify constant term in a scalar function

Use modify and ScalarConstantChange to modify the constant term in a ScalarAffineFunction or ScalarQuadraticFunction.

julia> c = MOI.add_constraint(           model,           MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, x)], 0.0),           MOI.EqualTo(1.0),       )MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.EqualTo{Float64}}(1)julia> MOI.modify(model, c, MOI.ScalarConstantChange(1.0));julia> new_f = MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, x)], 1.0);julia> MOI.get(model, MOI.ConstraintFunction(), c)  new_ftrue

ScalarConstantChange can also be used to modify the objective function by passing an instance of ObjectiveFunction:

julia> MOI.set(           model,           MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(),           new_f,       );julia> MOI.modify(           model,           MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(),           MOI.ScalarConstantChange(-1.0)       );julia> MOI.get(           model,           MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(),       )  MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, x)], -1.0)true

Modify constant terms in a vector function

Use modify and VectorConstantChange to modify the constant vector in a VectorAffineFunction or VectorQuadraticFunction.

julia> c = MOI.add_constraint(           model,           MOI.VectorAffineFunction([                   MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(1.0, x)),                   MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(2.0, x)),               ],               [0.0, 0.0],           ),           MOI.Nonnegatives(2),       )MathOptInterface.ConstraintIndex{MathOptInterface.VectorAffineFunction{Float64}, MathOptInterface.Nonnegatives}(1)julia> MOI.modify(model, c, MOI.VectorConstantChange([3.0, 4.0]));julia> new_f = MOI.VectorAffineFunction(           [        MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(1.0, x)),        MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(2.0, x)),           ],           [3.0, 4.0],       );julia> MOI.get(model, MOI.ConstraintFunction(), c)  new_ftrue

Modify affine coefficients in a scalar function

Use modify and ScalarCoefficientChange to modify the affine coefficient of a ScalarAffineFunction or ScalarQuadraticFunction.

julia> c = MOI.add_constraint(           model,           MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, x)], 0.0),           MOI.EqualTo(1.0),       )MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.EqualTo{Float64}}(1)julia> MOI.modify(model, c, MOI.ScalarCoefficientChange(x, 2.0));julia> new_f = MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(2.0, x)], 0.0);julia> MOI.get(model, MOI.ConstraintFunction(), c)  new_ftrue

ScalarCoefficientChange can also be used to modify the objective function by passing an instance of ObjectiveFunction.

Modify quadratic coefficients in a scalar function

Use modify and ScalarQuadraticCoefficientChange to modify the quadratic coefficient of a ScalarQuadraticFunction.

julia> model = MOI.Utilities.Model{Float64}();julia> x = MOI.add_variables(model, 2);julia> c = MOI.add_constraint(           model,           1.0 * x[1] * x[1] + 2.0 * x[1] * x[2],           MOI.EqualTo(1.0),       )MathOptInterface.ConstraintIndex{MathOptInterface.ScalarQuadraticFunction{Float64}, MathOptInterface.EqualTo{Float64}}(1)julia> MOI.modify(           model,           c,           MOI.ScalarQuadraticCoefficientChange(x[1], x[1], 3.0),       );julia> MOI.modify(           model,           c,           MOI.ScalarQuadraticCoefficientChange(x[1], x[2], 4.0),       );julia> new_f = 1.5 * x[1] * x[1] + 4.0 * x[1] * x[2];julia> MOI.get(model, MOI.ConstraintFunction(), c)  new_ftrue

ScalarQuadraticCoefficientChange can also be used to modify the objective function by passing an instance of ObjectiveFunction.

Modify affine coefficients in a vector function

Use modify and MultirowChange to modify a vector of affine coefficients in a VectorAffineFunction or a VectorQuadraticFunction.

julia> c = MOI.add_constraint(           model,           MOI.VectorAffineFunction([                   MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(1.0, x)),                   MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(2.0, x)),               ],               [0.0, 0.0],           ),           MOI.Nonnegatives(2),       )MathOptInterface.ConstraintIndex{MathOptInterface.VectorAffineFunction{Float64}, MathOptInterface.Nonnegatives}(1)julia> MOI.modify(model, c, MOI.MultirowChange(x, [(1, 3.0), (2, 4.0)]));julia> new_f = MOI.VectorAffineFunction(           [        MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(3.0, x)),        MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(4.0, x)),           ],           [0.0, 0.0],       );julia> MOI.get(model, MOI.ConstraintFunction(), c)  new_ftrue