# Gurobi callback in JuMP for submitting heuristic solution

**URL:** <https://discourse.julialang.org/t/gurobi-callback-in-jump-for-submitting-heuristic-solution/69006>\
**Category:** Optimization (Mathematical)\
**Tags:** jump\
**Created:** [September 30, 2021, 6:16pm UTC](https://discourse.julialang.org/t/gurobi-callback-in-jump-for-submitting-heuristic-solution/69006 "2021-09-30T18:16:19Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Shuvomoy\_Das\_Gupta](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shuvomoy_das_gupta/32/10069_2.png) [@Shuvomoy\_Das\_Gupta](https://discourse.julialang.org/u/Shuvomoy_Das_Gupta)\
**Post date:** [September 30, 2021, 6:16pm UTC](https://discourse.julialang.org/t/gurobi-callback-in-jump-for-submitting-heuristic-solution/69006/1 "2021-09-30T18:16:19Z")

</div>

Dear All,

I am trying to implement the fix-and-dive heuristic for the traveling salesman problem in `JuMP` with `Gurobi` based on the `Python+Gurobi` code available here: [https://github.com/Gurobi/pres-mipheur/blob/master/mipheurs.md#callback-for-fix-and-dive-heuristic](https://github.com/Gurobi/pres-mipheur/blob/master/mipheurs.md#callback-for-fix-and-dive-heuristic). This heuristic works as follows: when a fractional solution contains some variables at 1, we fix those and solve the smaller submodel, whose solution is then submitted as a heuristic solution. For convenience, I am recording the `Python+Gurobi` code below:

```python

# Callback for fix-and-dive heuristic
# -------------------------------------------

def fixcb(subcb=None):
    def inner(model, where):
        if where == GRB.Callback.MIPNODE:
            if model.cbGet(GRB.Callback.MIPNODE_STATUS) == GRB.OPTIMAL:
                # Try solving the fixed submodel
                fixed = model._fixed
                # Relaxed values near 1.0 get the lower bound set to 1.0
                for k,v in model.cbGetNodeRel(model._vars).items():
                    fixed._vars[k].LB = math.floor(v+0.01)
                # Set a cutoff for the fixed model, based on the current best solution
                if model.cbGet(GRB.Callback.MIPNODE_SOLCNT) > 0:
                    fixed.Params.Cutoff = model.cbGet(GRB.Callback.MIPNODE_OBJBST)
                fixed.optimize(tspcb(subcb)) # call subproblem callback
                if fixed.status == GRB.OPTIMAL:
                    fixedvals = fixed.getAttr('x', fixed._vars)
                    model.cbSetSolution(model._vars, fixedvals)
    return inner

# Create the fixed model
# ------------------------------

def tspmipwithfixed(n, dist):
    m = tspmip(n, dist) # main model
    m._fixed = tspmip(n, dist) # fixed model
    m._fixed.Params.OutputFlag = 0
    m._fixed._parent = m
    return m

```

The code requires to look at the existing fractional solution via `cbGetNodeRel`, and I am not sure how to do that in the Gurobi specific callback in [https://github.com/jump-dev/Gurobi.jl#callbacks](https://github.com/jump-dev/Gurobi.jl#callbacks). I will appreciate any tips/suggestion how to do the same thing via `Gurobi` specific callback or solver independent callback in Julia.

---

<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:** [September 30, 2021, 8:33pm UTC](https://discourse.julialang.org/t/gurobi-callback-in-jump-for-submitting-heuristic-solution/69006/2 "2021-09-30T20:33:33Z")

</div>

Use `callback_value` in a solver-independent callback:

- [Solver-independent Callbacks · JuMP](https://jump.dev/JuMP.jl/stable/manual/callbacks/#Heuristic-solutions)

Call `Gurobi.load_callback_variable_primal(cb_data, cb_where)` in a solver-dependent callback:

- [GitHub - jump-dev/Gurobi.jl: Julia interface for Gurobi Optimizer](https://github.com/jump-dev/Gurobi.jl#callbacks)
- [https://github.com/jump-dev/Gurobi.jl/blob/af5b927ff51d2f2df42de935cc35e27b6e52569d/src/MOI\_wrapper/MOI\_callbacks.jl#L92-L104](https://github.com/jump-dev/Gurobi.jl/blob/af5b927ff51d2f2df42de935cc35e27b6e52569d/src/MOI_wrapper/MOI_callbacks.jl#L92-L104)

The solver-specific callbacks use the C API, so you should look at those examples, not the Python ones.

---

<div class="post-metadata">

**Author:** ![Shuvomoy\_Das\_Gupta](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shuvomoy_das_gupta/32/10069_2.png) [@Shuvomoy\_Das\_Gupta](https://discourse.julialang.org/u/Shuvomoy_Das_Gupta)\
**Post date:** [September 30, 2021, 8:40pm UTC](https://discourse.julialang.org/t/gurobi-callback-in-jump-for-submitting-heuristic-solution/69006/3 "2021-09-30T20:40:52Z")

</div>

Sounds good, thanks @odow !
