# Capturing best solution from a JuMP model that times out

**URL:** <https://discourse.julialang.org/t/capturing-best-solution-from-a-jump-model-that-times-out/122807>\
**Category:** Optimization (Mathematical)\
**Created:** [November 19, 2024, 10:59am UTC](https://discourse.julialang.org/t/capturing-best-solution-from-a-jump-model-that-times-out/122807 "2024-11-19T10:59:24Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [November 19, 2024, 10:59am UTC](https://discourse.julialang.org/t/capturing-best-solution-from-a-jump-model-that-times-out/122807/1 "2024-11-19T10:59:24Z")

</div>

I have a mixed integer problem that I think is sufficiently hard that it won’t complete in sensible time.

I am probably using HiGHS.

I would like to see the best feasible solution that was found.  
Actually I might like to see a bunch of solution that were tested, maybe all of them.

One idea is maybe I could use solver independent callbacks to write them to a global variable.

if JuMP is terminated via timeout will the solution object be set to the best it has found?

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [November 19, 2024, 11:30am UTC](https://discourse.julialang.org/t/capturing-best-solution-from-a-jump-model-that-times-out/122807/2 "2024-11-19T11:30:29Z")

</div>

> [@oxinabox](#):
>
> if JuMP is terminated via timeout will the solution object be set to the best it has found?

Yes. At least that’s my understanding and what I’ve observed with HiGHS.

EDIT: to be clearer, I analyze my MILP results with code similar to this:

```julia
optimize!(model)
if termination_status(model) == TIME_LIMIT
    if primal_status(model) == FEASIBLE_POINT
        @warn "Time limit with feasible solution" code=termination_status(model) status=raw_status(model)
    else
        @error "Time limit without any feasible solution" code=termination_status(model) status=raw_status(model)
        throw(Infeasible())
    end
elseif termination_status(model) != OPTIMAL
    @error "JuMP did not solve to optimality" code=termination_status(model) status=raw_status(model)
    throw(Infeasible())
end

```

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [November 19, 2024, 7:58pm UTC](https://discourse.julialang.org/t/capturing-best-solution-from-a-jump-model-that-times-out/122807/3 "2024-11-19T19:58:21Z")

</div>

@ffevotte is correct here 😄

> if JuMP is terminated via timeout will the solution object be set to the best it has found?

It depends on the solver, and whether the solver found a feasible solution before the time limit.

But yes, you can use `primal_status(model)` to check if it is a `FEASIBLE_POINT`, and `termination_status(model)` to check whether the point is `OPTIMAL` or suboptimal because of a limit like `TIME_LIMIT`.

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [November 22, 2024, 5:32am UTC](https://discourse.julialang.org/t/capturing-best-solution-from-a-jump-model-that-times-out/122807/4 "2024-11-22T05:32:02Z")

</div>

What if I want to acquire a list of all feasible solutions considered by the solver?

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [November 22, 2024, 5:40am UTC](https://discourse.julialang.org/t/capturing-best-solution-from-a-jump-model-that-times-out/122807/5 "2024-11-22T05:40:28Z")

</div>

Maybe using a callback and storing the solutions in the callback function is the way to go. Don’t know how drastic the performance hit would be.  
Link to callback doc: [Solver-independent Callbacks · JuMP](https://jump.dev/JuMP.jl/stable/manual/callbacks/)

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [November 22, 2024, 6:59am UTC](https://discourse.julialang.org/t/capturing-best-solution-from-a-jump-model-that-times-out/122807/6 "2024-11-22T06:59:54Z")

</div>

This depends heavily on the solver.

With Gurobi, you can set some parameters: [Finding multiple feasible solutions | JuMP](https://jump.dev/tutorials/2021/11/02/tutorial-multi-jdf/) We should probably figure out how to add that to the docs.

With HiGHS, there’s no easy way. It’d need to be something like this, but the callback is still somewhat immature so it is not documented.

```julia
using JuMP, HiGHS
model = Model(HiGHS.Optimizer)
N = 100
@variable(model, 0 <= x[1:N] <= 2, Int)
@constraint(model, rand(N)' * x <= 0.1 * N)
@objective(model, Max, rand(N)' * x)
solutions = Vector{Float64}[]
function user_callback(
    callback_type::Cint,
    message::Ptr{Cchar},
    data_out::HiGHS.HighsCallbackDataOut,
)::Cint
    if callback_type == kHighsCallbackMipSolution
        p::Ptr{Cdouble} = Highs_getCallbackDataOutItem(Ref(data_out), "mip_solution")
        push!(solutions, copy(unsafe_wrap(Array, p, N)))
    end
    return 0
end
set_attribute(model, HiGHS.CallbackFunction(), user_callback)
optimize!(model)
unique(solutions)

```
