# Solutions

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

## Basic utilities

JuMP.optimize!Function
optimize!(model::Model;
ignore_optimize_hook=(model.optimize_hook === nothing),
kwargs...)

Optimize the model. If an optimizer has not been set yet (see set_optimizer), a NoOptimizer error is thrown.

Keyword arguments kwargs are passed to the optimize_hook. An error is thrown if optimize_hook is nothing and keyword arguments are provided.

source
JuMP.solution_summaryFunction
solution_summary(model::Model; verbose::Bool = false)

Return a struct that can be used print a summary of the solution.

If verbose=true, write out the primal solution for every variable and the dual solution for every constraint, excluding those with empty names.

Examples

When called at the REPL, the summary is automatically printed:

julia> solution_summary(model)
[...]

Use print to force the printing of the summary from inside a function:

function foo(model)
print(solution_summary(model))
return
end
source

## Termination status

JuMP.raw_statusFunction
raw_status(model::Model)

Return the reason why the solver stopped in its own words (i.e., the MathOptInterface model attribute RawStatusString).

source

## Primal solutions

JuMP.has_valuesFunction
has_values(model::Model; result::Int = 1)

Return true if the solver has a primal solution in result index result available to query, otherwise return false.

source
JuMP.valueFunction
value(con_ref::ConstraintRef; result::Int = 1)

Return the primal value of constraint con_ref associated with result index result of the most-recent solution returned by the solver.

That is, if con_ref is the reference of a constraint func-in-set, it returns the value of func evaluated at the value of the variables (given by value(::VariableRef)).

Use has_values to check if a result exists before asking for values.

Note

For scalar constraints, the constant is moved to the set so it is not taken into account in the primal value of the constraint. For instance, the constraint @constraint(model, 2x + 3y + 1 == 5) is transformed into 2x + 3y-in-MOI.EqualTo(4) so the value returned by this function is the evaluation of 2x + 3y. 

source
value(var_value::Function, con_ref::ConstraintRef)

Evaluate the primal value of the constraint con_ref using var_value(v) as the value for each variable v.

source
value(v::VariableRef; result = 1)

Return the value of variable v associated with result index result of the most-recent returned by the solver.

Use has_values to check if a result exists before asking for values.

source
value(var_value::Function, v::VariableRef)

Evaluate the value of the variable v as var_value(v).

source
value(var_value::Function, ex::GenericAffExpr)

Evaluate ex using var_value(v) as the value for each variable v.

source
value(v::GenericAffExpr; result::Int = 1)

Return the value of the GenericAffExpr v associated with result index result of the most-recent solution returned by the solver.

source

Evaluate ex using var_value(v) as the value for each variable v.

source

Return the value of the GenericQuadExpr v associated with result index result of the most-recent solution returned by the solver.

Replaces getvalue for most use cases.

source
value(p::NonlinearParameter)

Return the current value stored in the nonlinear parameter p.

Example

model = Model()
@NLparameter(model, p == 10)
value(p)

# output
10.0
source
value(var_value::Function, ex::NonlinearExpression)

Evaluate ex using var_value(v) as the value for each variable v.

source
value(ex::NonlinearExpression; result::Int = 1)

Return the value of the NonlinearExpression ex associated with result index result of the most-recent solution returned by the solver.

Replaces getvalue for most use cases.

source

## Dual solutions

JuMP.dualFunction
dual(con_ref::ConstraintRef; result::Int = 1)

Return the dual value of constraint con_ref associated with result index result of the most-recent solution returned by the solver.

Use has_dual to check if a result exists before asking for values.

source
dual(c::NonlinearConstraintRef)

Return the dual of the nonlinear constraint c.

source

Return the change in the objective from an infinitesimal relaxation of the constraint.

This value is computed from dual and can be queried only when has_duals is true and the objective sense is MIN_SENSE or MAX_SENSE (not FEASIBILITY_SENSE). For linear constraints, the shadow prices differ at most in sign from the dual value depending on the objective sense.

Notes

• The function simply translates signs from dual and does not validate the conditions needed to guarantee the sensitivity interpretation of the shadow price. The caller is responsible, e.g., for checking whether the solver converged to an optimal primal-dual pair or a proof of infeasibility.
• The computation is based on the current objective sense of the model. If this has changed since the last solve, the results will be incorrect.
• Relaxation of equality constraints (and hence the shadow price) is defined based on which sense of the equality constraint is active.
source
JuMP.reduced_costFunction
reduced_cost(x::VariableRef)::Float64

Return the reduced cost associated with variable x.

Equivalent to querying the shadow price of the active variable bound (if one exists and is active).

source

## Basic attributes

JuMP.objective_valueFunction
objective_value(model::Model; result::Int = 1)

Return the objective value associated with result index result of the most-recent solution returned by the solver.

source
JuMP.objective_boundFunction
objective_bound(model::Model)

Return the best known bound on the optimal objective value after a call to optimize!(model).

source
JuMP.dual_objective_valueFunction
dual_objective_value(model::Model; result::Int = 1)

Return the value of the objective of the dual problem associated with result index result of the most-recent solution returned by the solver.

Throws MOI.UnsupportedAttribute{MOI.DualObjectiveValue} if the solver does not support this attribute.

source
JuMP.solve_timeFunction
solve_time(model::Model)

If available, returns the solve time reported by the solver. Returns "ArgumentError: ModelLike of type Solver.Optimizer does not support accessing the attribute MathOptInterface.SolveTimeSec()" if the attribute is not implemented.

source
JuMP.relative_gapFunction
relative_gap(model::Model)

Return the final relative optimality gap after a call to optimize!(model). Exact value depends upon implementation of MathOptInterface.RelativeGap() by the particular solver used for optimization.

source
JuMP.simplex_iterationsFunction
simplex_iterations(model::Model)

Gets the cumulative number of simplex iterations during the most-recent optimization.

Solvers must implement MOI.SimplexIterations() to use this function.

source
JuMP.barrier_iterationsFunction
barrier_iterations(model::Model)

Gets the cumulative number of barrier iterations during the most recent optimization.

Solvers must implement MOI.BarrierIterations() to use this function.

source
JuMP.node_countFunction
node_count(model::Model)

Gets the total number of branch-and-bound nodes explored during the most recent optimization in a Mixed Integer Program.

Solvers must implement MOI.NodeCount() to use this function.

source

## Conflicts

JuMP.compute_conflict!Function
compute_conflict!(model::Model)

Compute a conflict if the model is infeasible. If an optimizer has not been set yet (see set_optimizer), a NoOptimizer error is thrown.

The status of the conflict can be checked with the MOI.ConflictStatus model attribute. Then, the status for each constraint can be queried with the MOI.ConstraintConflictStatus attribute.

source
JuMP.copy_conflictFunction
copy_conflict(model::Model)

Return a copy of the current conflict for 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.

This is a convenience function that provides a filtering function for copy_model.

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 two constraints cref and cref2. This model has no solution, as the two constraints are mutually exclusive. The solver is asked to compute a conflict with compute_conflict!. The parts of model participating in the conflict are then copied into a model new_model.

model = Model() # You must use a solver that supports conflict refining/IIS
# computation, like CPLEX or Gurobi
@variable(model, x)
@constraint(model, cref, x >= 2)
@constraint(model, cref2, x <= 1)

compute_conflict!(model)
if MOI.get(model, MOI.ConflictStatus()) != MOI.CONFLICT_FOUND
error("No conflict could be found for an infeasible model.")
end

new_model, reference_map = copy_conflict(model)
source

## Sensitivity

JuMP.lp_sensitivity_reportFunction
lp_sensitivity_report(model::Model; atol::Float64 = 1e-8)::SensitivityReport

Given a linear program model with a current optimal basis, return a SensitivityReport object, which maps:

• Every variable reference to a tuple (d_lo, d_hi)::Tuple{Float64,Float64}, explaining how much the objective coefficient of the corresponding variable can change by, such that the original basis remains optimal.
• Every constraint reference to a tuple (d_lo, d_hi)::Tuple{Float64,Float64}, explaining how much the right-hand side of the corresponding constraint can change by, such that the basis remains optimal.

Both tuples are relative, rather than absolute. So given a objective coefficient of 1.0 and a tuple (-0.5, 0.5), the objective coefficient can range between 1.0 - 0.5 an 1.0 + 0.5.

atol is the primal/dual optimality tolerance, and should match the tolerance of the solver used to compute the basis.

Note: interval constraints are NOT supported.

Example

model = Model(GLPK.Optimizer)
@variable(model, -1 <= x <= 2)
@objective(model, Min, x)
optimize!(model)
report = lp_sensitivity_report(model; atol = 1e-7)
dx_lo, dx_hi = report[x]
println(
"The objective coefficient of x can decrease by $dx_lo or " * "increase by$dx_hi."
)
c = LowerBoundRef(x)
dRHS_lo, dRHS_hi = report[c]
println(
"The lower bound of x` can decrease by $dRHS_lo or increase " * "by$dRHS_hi."
)
source

## Feasibility

JuMP.primal_feasibility_reportFunction
primal_feasibility_report(
model::Model,
point::AbstractDict{VariableRef,Float64} = _last_primal_solution(model),
atol::Float64 = 0.0,
skip_missing::Bool = false,
)::Dict{Any,Float64}

Given a dictionary point, which maps variables to primal values, return a dictionary whose keys are the constraints with an infeasibility greater than the supplied tolerance atol. The value corresponding to each key is the respective infeasibility. Infeasibility is defined as the distance between the primal value of the constraint (see MOI.ConstraintPrimal) and the nearest point by Euclidean distance in the corresponding set.

Notes

• If skip_missing = true, constraints containing variables that are not in point will be ignored.
• If skip_missing = false and a partial primal solution is provided, an error will be thrown.
• If no point is provided, the primal solution from the last time the model was solved is used.

Examples

julia> model = Model();

julia> @variable(model, 0.5 <= x <= 1);

julia> primal_feasibility_report(model, Dict(x => 0.2))
Dict{Any,Float64} with 1 entry:
x ≥ 0.5 => 0.3
source
primal_feasibility_report(
point::Function,
model::Model;
atol::Float64 = 0.0,
skip_missing::Bool = false,
)

A form of primal_feasibility_report where a function is passed as the first argument instead of a dictionary as the second argument.

Examples

julia> model = Model();

julia> @variable(model, 0.5 <= x <= 1);

julia> primal_feasibility_report(model) do v
return value(v)
end
Dict{Any,Float64} with 1 entry:
x ≥ 0.5 => 0.3
source