# Models

More information can be found in the Models section of the manual.

## Constructors

JuMP.direct_modelFunction
direct_model(backend::MOI.ModelLike)

Return a new JuMP model using backend to store the model and solve it.

As opposed to the Model constructor, no cache of the model is stored outside of backend and no bridges are automatically applied to backend.

Notes

The absence of a cache reduces the memory footprint but, it is important to bear in mind the following implications of creating models using this direct mode:

• When backend does not support an operation, such as modifying constraints or adding variables/constraints after solving, an error is thrown. For models created using the Model constructor, such situations can be dealt with by storing the modifications in a cache and loading them into the optimizer when optimize! is called.
• No constraint bridging is supported by default.
• The optimizer used cannot be changed the model is constructed.
• The model created cannot be copied.
source
direct_model(factory::MOI.OptimizerWithAttributes)

Create a direct_model using factory, a MOI.OptimizerWithAttributes object created by optimizer_with_attributes.

Example

model = direct_model(
optimizer_with_attributes(
Gurobi.Optimizer,
"Presolve" => 0,
"OutputFlag" => 1,
)
)

is equivalent to:

model = direct_model(Gurobi.Optimizer())
set_optimizer_attribute(model, "Presolve", 0)
set_optimizer_attribute(model, "OutputFlag", 1)
source

## Enums

JuMP.DIRECTConstant

moi_backend field holds an AbstractOptimizer. No extra copy of the model is stored. The moi_backend must support add_constraint etc.

source

## Basic functions

JuMP.backendFunction
backend(model::Model)

Return the lower-level MathOptInterface model that sits underneath JuMP. This model depends on which operating mode JuMP is in (see mode).

• If JuMP is in DIRECT mode (i.e., the model was created using direct_model), the backend will be the optimizer passed to direct_model.
• If JuMP is in MANUAL or AUTOMATIC mode, the backend is a MOI.Utilities.CachingOptimizer.

This function should only be used by advanced users looking to access low-level MathOptInterface or solver-specific functionality.

Notes

If JuMP is not in DIRECT mode, the type returned by backend may change between any JuMP releases. Therefore, only use the public API exposed by MathOptInterface, and do not access internal fields. If you require access to the innermost optimizer, see unsafe_backend. Alternatively, use direct_model to create a JuMP model in DIRECT mode.

See also: unsafe_backend.

source
JuMP.unsafe_backendFunction
unsafe_backend(model::Model)

Return the innermost optimizer associated with the JuMP model model.

This function should only be used by advanced users looking to access low-level solver-specific functionality. It has a high-risk of incorrect usage. We strongly suggest you use the alternative suggested below.

See also: backend.

Unsafe behavior

This function is unsafe for two main reasons.

First, the formulation and order of variables and constraints in the unsafe backend may be different to the variables and constraints in model. This can happen because of bridges, or because the solver requires the variables or constraints in a specific order. In addition, the variable or constraint index returned by index at the JuMP level may be different to the index of the corresponding variable or constraint in the unsafe_backend. There is no solution to this. Use the alternative suggested below instead.

Second, the unsafe_backend may be empty, or lack some modifications made to the JuMP model. Thus, before calling unsafe_backend you should first call MOI.Utilities.attach_optimizer to ensure that the backend is synchronized with the JuMP model.

MOI.Utilities.attach_optimizer(model)
inner = unsafe_backend(model)

Moreover, if you modify the JuMP model, the reference you have to the backend (i.e., inner in the example above) may be out-dated, and you should call MOI.Utilities.attach_optimizer again.

This function is also unsafe in the reverse direction: if you modify the unsafe backend, e.g., by adding a new constraint to inner, the changes may be silently discarded by JuMP when the JuMP model is modified or solved.

Alternative

Instead of unsafe_backend, create a model using direct_model and call backend instead.

model = Model(HiGHS.Optimizer)
@variable(model, x >= 0)
MOI.Utilities.attach_optimizer(model)
highs = unsafe_backend(model)

Use:

model = direct_model(HiGHS.Optimizer())
@variable(model, x >= 0)
highs = backend(model)  # No need to call attach_optimizer.
source
JuMP.solver_nameFunction
solver_name(model::Model)

If available, returns the SolverName property of the underlying optimizer.

Returns "No optimizer attached" in AUTOMATIC or MANUAL modes when no optimizer is attached.

Returns "SolverName() attribute not implemented by the optimizer." if the attribute is not implemented.

source
Base.empty!Method
empty!(model::Model)::Model

Empty the model, that is, remove all variables, constraints and model attributes but not optimizer attributes. Always return the argument.

Note: removes extensions data.

source
Base.isemptyMethod
isempty(model::Model)

Verifies whether the model is empty, that is, whether the MOI backend is empty and whether the model is in the same state as at its creation apart from optimizer attributes.

source
JuMP.object_dictionaryFunction
object_dictionary(model::Model)

Return the dictionary that maps the symbol name of a variable, constraint, or expression to the corresponding object.

Objects are registered to a specific symbol in the macros. For example, @variable(model, x[1:2, 1:2]) registers the array of variables x to the symbol :x.

This method should be defined for any subtype of AbstractModel.

source
JuMP.unregisterFunction
unregister(model::Model, key::Symbol)

Unregister the name key from model so that a new variable, constraint, or expression can be created with the same key.

Note that this will not delete the object model[key]; it will just remove the reference at model[key]. To delete the object, use

delete(model, model[key])
unregister(model, key)

See also: object_dictionary.

Examples

julia> @variable(model, x)
x

julia> @variable(model, x)
ERROR: An object of name x is already attached to this model. If
this is intended, consider using the anonymous construction syntax,
e.g., x = @variable(model, [1:N], ...) where the name of the object
does not appear inside the macro.

Alternatively, use unregister(model, :x) to first unregister the
existing name from the model. Note that this will not delete the object;
it will just remove the reference at model[:x].
[...]

julia> num_variables(model)
1

julia> unregister(model, :x)

julia> @variable(model, x)
x

julia> num_variables(model)
2
source
JuMP.latex_formulationFunction
latex_formulation(model::AbstractModel)

Wrap model in a type so that it can be pretty-printed as text/latex in a notebook like IJulia, or in Documenter.

To render the model, end the cell with latex_formulation(model), or call display(latex_formulation(model)) in to force the display of the model from inside a function.

source
JuMP.set_string_names_on_creationFunction
set_string_names_on_creation(model::Model, value::Bool)

Set the default argument of the set_string_name keyword in the @variable and @constraint macros to value. This is used to determine whether to assign String names to all variables and constraints in model.

By default, value is true. However, for larger models calling set_string_names_on_creation(model, false) can improve performance at the cost of reducing the readability of printing and solver log messages.

source

## Working with attributes

JuMP.set_optimizerFunction
set_optimizer(
model::Model,
optimizer_factory;
)

Creates an empty MathOptInterface.AbstractOptimizer instance by calling optimizer_factory() and sets it as the optimizer of model. Specifically, optimizer_factory must be callable with zero arguments and return an empty MathOptInterface.AbstractOptimizer.

If add_bridges is true, constraints and objectives that are not supported by the optimizer are automatically bridged to equivalent supported formulation. Passing add_bridges = false can improve performance if the solver natively supports all of the elements in model.

See set_optimizer_attributes and set_optimizer_attribute for setting solver-specific parameters of the optimizer.

Examples

model = Model()
set_optimizer(model, HiGHS.Optimizer)
set_optimizer(model, HiGHS.Optimizer; add_bridges = false)
source
JuMP.optimizer_with_attributesFunction
optimizer_with_attributes(optimizer_constructor, attrs::Pair...)

Groups an optimizer constructor with the list of attributes attrs. Note that it is equivalent to MOI.OptimizerWithAttributes.

When provided to the Model constructor or to set_optimizer, it creates an optimizer by calling optimizer_constructor(), and then sets the attributes using set_optimizer_attribute.

Example

model = Model(
optimizer_with_attributes(
Gurobi.Optimizer, "Presolve" => 0, "OutputFlag" => 1
)
)

is equivalent to:

model = Model(Gurobi.Optimizer)
set_optimizer_attribute(model, "Presolve", 0)
set_optimizer_attribute(model, "OutputFlag", 1)

Note

The string names of the attributes are specific to each solver. One should consult the solver's documentation to find the attributes of interest.

source
JuMP.get_optimizer_attributeFunction
get_optimizer_attribute(model, name::String)

Return the value associated with the solver-specific attribute named name.

Note that this is equivalent to get_optimizer_attribute(model, MOI.RawOptimizerAttribute(name)).

Example

get_optimizer_attribute(model, "SolverSpecificAttributeName")
source
get_optimizer_attribute(
model::Model, attr::MOI.AbstractOptimizerAttribute
)

Return the value of the solver-specific attribute attr in model.

Example

get_optimizer_attribute(model, MOI.Silent())
source
JuMP.set_optimizer_attributeFunction
set_optimizer_attribute(model::Model, name::String, value)

Sets solver-specific attribute identified by name to value.

Note that this is equivalent to set_optimizer_attribute(model, MOI.RawOptimizerAttribute(name), value).

Example

set_optimizer_attribute(model, "SolverSpecificAttributeName", true)
source
set_optimizer_attribute(
model::Model,
attr::MOI.AbstractOptimizerAttribute,
value,
)

Set the solver-specific attribute attr in model to value.

Example

set_optimizer_attribute(model, MOI.Silent(), true)
source
JuMP.set_optimizer_attributesFunction
set_optimizer_attributes(model::Model, pairs::Pair...)

Given a list of attribute => value pairs, calls set_optimizer_attribute(model, attribute, value) for each pair.

Example

model = Model(Ipopt.Optimizer)
set_optimizer_attributes(model, "tol" => 1e-4, "max_iter" => 100)

is equivalent to:

model = Model(Ipopt.Optimizer)
set_optimizer_attribute(model, "tol", 1e-4)
set_optimizer_attribute(model, "max_iter", 100)
source
JuMP.time_limit_secFunction
time_limit_sec(model::Model)

Return the time limit (in seconds) of the model.

Returns nothing if unset.

source

## Copying

JuMP.ReferenceMapType
ReferenceMap

Mapping between variable and constraint reference of a model and its copy. The reference of the copied model can be obtained by indexing the map with the reference of the corresponding reference of the original model.

source
JuMP.copy_modelFunction
copy_model(model::Model; filter_constraints::Union{Nothing, Function}=nothing)

Return a copy of the model model and a ReferenceMap that can be used to obtain the variable and constraint reference of the new model corresponding to a given model's reference. A Base.copy(::AbstractModel) method has also been implemented, it is similar to copy_model but does not return the reference map.

If the filter_constraints argument is given, only the constraints for which this function returns true will be copied. This function is given a constraint reference as argument.

Note

Model copy is not supported in DIRECT mode, i.e. when a model is constructed using the direct_model constructor instead of the Model constructor. Moreover, independently on whether an optimizer was provided at model construction, the new model will have no optimizer, i.e., an optimizer will have to be provided to the new model in the optimize! call.

Examples

In the following example, a model model is constructed with a variable x and a constraint cref. It is then copied into a model new_model with the new references assigned to x_new and cref_new.

model = Model()
@variable(model, x)
@constraint(model, cref, x == 2)

new_model, reference_map = copy_model(model)
x_new = reference_map[x]
cref_new = reference_map[cref]
source
JuMP.copy_extension_dataFunction
copy_extension_data(data, new_model::AbstractModel, model::AbstractModel)

Return a copy of the extension data data of the model model to the extension data of the new model new_model.

A method should be added for any JuMP extension storing data in the ext field.

Warning

Do not engage in type piracy by implementing this method for types of data that you did not define! JuMP extensions should store types that they define in model.ext, rather than regular Julia types.

source
Base.copyMethod
copy(model::AbstractModel)

Return a copy of the model model. It is similar to copy_model except that it does not return the mapping between the references of model and its copy.

Note

Model copy is not supported in DIRECT mode, i.e. when a model is constructed using the direct_model constructor instead of the Model constructor. Moreover, independently on whether an optimizer was provided at model construction, the new model will have no optimizer, i.e., an optimizer will have to be provided to the new model in the optimize! call.

Examples

In the following example, a model model is constructed with a variable x and a constraint cref. It is then copied into a model new_model with the new references assigned to x_new and cref_new.

model = Model()
@variable(model, x)
@constraint(model, cref, x == 2)

new_model = copy(model)
x_new = model[:x]
cref_new = model[:cref]
source

## I/O

JuMP.write_to_fileFunction
write_to_file(
model::Model,
filename::String;
format::MOI.FileFormats.FileFormat = MOI.FileFormats.FORMAT_AUTOMATIC,
kwargs...,
)

Write the JuMP model model to filename in the format format.

If the filename ends in .gz, it will be compressed using Gzip. If the filename ends in .bz2, it will be compressed using BZip2.

Other kwargs are passed to the Model constructor of the chosen format.

source
Base.writeMethod
Base.write(
io::IO,
model::Model;
format::MOI.FileFormats.FileFormat = MOI.FileFormats.FORMAT_MOF,
kwargs...,
)

Write the JuMP model model to io in the format format.

Other kwargs are passed to the Model constructor of the chosen format.

source
JuMP.read_from_fileFunction
read_from_file(
filename::String;
format::MOI.FileFormats.FileFormat = MOI.FileFormats.FORMAT_AUTOMATIC,
kwargs...,
)

Return a JuMP model read from filename in the format format.

If the filename ends in .gz, it will be uncompressed using Gzip. If the filename ends in .bz2, it will be uncompressed using BZip2.

Other kwargs are passed to the Model constructor of the chosen format.

source
Base.readMethod
Base.read(
io::IO,
::Type{Model};
format::MOI.FileFormats.FileFormat,
kwargs...,
)

Return a JuMP model read from io in the format format.

Other kwargs are passed to the Model constructor of the chosen format.

source

## Bridge tools

JuMP.bridge_constraintsFunction
bridge_constraints(model::Model)

When in direct mode, return false. When in manual or automatic mode, return a Bool indicating whether the optimizer is set and unsupported constraints are automatically bridged to equivalent supported constraints when an appropriate transformation is available.

source
JuMP.print_bridge_graphFunction
 print_bridge_graph([io::IO,] model::Model)

Print the hyper-graph containing all variable, constraint, and objective types that could be obtained by bridging the variables, constraints, and objectives that are present in the model.

Each node in the hyper-graph corresponds to a variable, constraint, or objective type.

• Variable nodes are indicated by [ ]
• Constraint nodes are indicated by ( )
• Objective nodes are indicated by | |

The number inside each pair of brackets is an index of the node in the hyper-graph.

Note that this hyper-graph is the full list of possible transformations. When the bridged model is created, we select the shortest hyper-path(s) from this graph, so many nodes may be un-used.

For more information, see Legat, B., Dowson, O., Garcia, J., and Lubin, M. (2020). "MathOptInterface: a data structure for mathematical optimization problems." URL: https://arxiv.org/abs/2002.03447

source

## Extension tools

JuMP.operator_warnFunction
operator_warn(model::AbstractModel)
operator_warn(model::Model)

This function is called on the model whenever two affine expressions are added together without using destructive_add!, and at least one of the two expressions has more than 50 terms.

For the case of Model, if this function is called more than 20,000 times then a warning is generated once.

source
JuMP.error_if_direct_modeFunction
error_if_direct_mode(model::Model, func::Symbol)

Errors if model is in direct mode during a call from the function named func.

Used internally within JuMP, or by JuMP extensions who do not want to support models in direct mode.

source
JuMP.set_optimize_hookFunction
set_optimize_hook(model::Model, f::Union{Function,Nothing})

Set the function f as the optimize hook for model.

f should have a signature f(model::Model; kwargs...), where the kwargs are those passed to optimize!.

Notes

• The optimize hook should generally modify the model, or some external state in some way, and then call optimize!(model; ignore_optimize_hook = true) to optimize the problem, bypassing the hook.
• Use set_optimize_hook(model, nothing) to unset an optimize hook.

Examples

model = Model()
function my_hook(model::Model; kwargs...)
print(kwargs)
return optimize!(model; ignore_optimize_hook = true)
end
set_optimize_hook(model, my_hook)
optimize!(model; test_arg = true)
source