About JuMP.is_solved_and_feasible

We’re open to suggestions for improving the solution summary. How about:

Solution summary
├ solver_name : Gurobi
├ Overall status
│ ├ termination_status : OPTIMAL
│ ├ result_count       : 3
│ ├ objective_bound    : -3.00000e+00
│ ├ relative_gap       : 0.00000e+00
│ └ raw_status
│   └ "Model was solved to optimality (subject to tolerances), and an optimal solution is available."
├ Candidate solution (; result = 1)
│ ├ primal_status        : FEASIBLE_POINT
│ ├ dual_status          : NO_SOLUTION
│ ├ objective_value      : -3.00000e+00
│ └ dual_objective_value : -3.00000e+00
└ Work counters
  ├ solve_time (sec)   : 3.03030e-04
  ├ simplex_iterations : 0
  ├ barrier_iterations : 0
  └ node_count         : 0

I would suggest that add a dynamic (3-possibilities) lb and ub hint.
(part of summary are something like):
For a Min-Program:


├ ObjSense: MIN_SENSE

├ termination_status: TIME_LIMIT

├ objective_bound (lb): -3.0

├ Candidate solution (; result = 1)

│ ├ objective_value (ub): -2.0

For a Max-Program


├ ObjSense: MAX_SENSE

├ termination_status: TIME_LIMIT

├ objective_bound (ub): -2.0

├ Candidate solution (; result = 1)

│ ├ objective_value (lb): -3.0

For a Feasibility-Problem


ObjSense: FEASIBILITY_SENSE (Did you forget to specify?)

termination_status: TIME_LIMIT

Candidate solution (; result = 1)

Which smart solver showcases this behavior? I wonder.

Which smart solver showcases this behavior? I wonder.

CPLEX: IBM Documentation

Also following up to say that the next release of JuMP features a revamped solution summary:

julia> solution_summary(model; verbose = true)
solution_summary(; result = 1, verbose = true)
├ solver_name          : Gurobi
├ Termination
│ ├ termination_status : OPTIMAL
│ ├ result_count       : 3
│ ├ raw_status         : Model was solved to optimality (subject to tolerances), and an optimal solution is available.
│ └ objective_bound    : -3.00000e+00
├ Solution (result = 1)
│ ├ primal_status        : FEASIBLE_POINT
│ ├ dual_status          : NO_SOLUTION
│ ├ objective_value      : -3.00000e+00
│ ├ relative_gap         : 0.00000e+00
│ └ value
│   ├ x : 1.00000e+00
│   └ y : 4.00000e+00
└ Work counters
  ├ solve_time (sec)   : 3.06129e-04
  ├ simplex_iterations : 0
  ├ barrier_iterations : 0
  └ node_count         : 0
1 Like

Fortunately I have never used Cplex. It’s awkward.
I think it should report INFEASIBLE directly in this case.
OPTIMAL should be a definite answer which by itself implies normality.

1 Like

We cannot report termination_status(model) == INFEASIBLE because CPLEX did not prove that the problem is infeasible.

I looked at the code. We actually report the termination status as ALMOST_INFEASIBLE which seems somewhat appropriate:

My larger point is that you should not rely on termination_status alone. You must always check it in combination with primal_status.

Yes, there are circumstances where we have no primal solution but the JuMP.objective_bound functions (verb) properly, and it may function properly both in pure-LP and MIP. I can furnish code instances to reproduce this situation, with Gurobi.