# Multiple solve, same script

**URL:** <https://discourse.julialang.org/t/multiple-solve-same-script/105874>\
**Category:** Optimization (Mathematical)\
**Tags:** jump, gurobi\
**Created:** [November 6, 2023, 6:59pm UTC](https://discourse.julialang.org/t/multiple-solve-same-script/105874 "2023-11-06T18:59:15Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![martina.gherardi](https://avatars.discourse-cdn.com/v4/letter/m/90ced4/32.png) [@martina.gherardi](https://discourse.julialang.org/u/martina.gherardi)\
**Post date:** [November 6, 2023, 6:59pm UTC](https://discourse.julialang.org/t/multiple-solve-same-script/105874/1 "2023-11-06T18:59:15Z")

</div>

Hi,  
I would like to ask a question about the JuMP’s internal procedure for solving similar problems in the same script.

I follow these steps:

1. Write a model called `MyMod`
2. Call `optimize!(MyMod)` to solve it
3. Add some constraints `@constraint(MyMod,...)`.
4. Call `optimize!(MyMod)` again to solve the model with the same name

Note that I use Gurobi.

In the log, after the first solution, I see

> MIP start from previous solution did not produce a new incumbent solution

This leads me to believe that the second solution is warm started with the optimal values of the variables found in the first solution.

- Is this correct?
- Are all variable values from the first solution transferred to the second solution?

If I explicitly put the warm start before the 4th step with

```julia
var = all_variables(MyMod)
var_solution = value.(var)
set_start_value.(var,var_solution)

```

I get a different result. In particular, it finds a feasible solution with

```julia
Another try with MIP start

```

Thank you in advance for the help

---

<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 6, 2023, 8:41pm UTC](https://discourse.julialang.org/t/multiple-solve-same-script/105874/2 "2023-11-06T20:41:10Z")

</div>

> Is this correct?

Yes

> Are all variable values from the first solution transferred to the second solution?

Yes

> I get a different result. In particular, it finds a feasible solution with

Okay, so the difference is _very_ subtle.

In the first case, Gurobi automatically re-uses the previous solution as a starting point. (We don’t tell it to.) But it obviously doesn’t try very hard to repair feasibility, and so it doesn’t produce a new incumbent.

In the second case, you are explicitly telling Gurobi “here is a starting solution that should be close to feasible/optimal,” to it runs a feasibility repair heuristic that attempts to find a solution close to your starting point. That succeeds.

@vasyfa works for Gurobi and might be able to offer more insight.

---

<div class="post-metadata">

**Author:** ![martina.gherardi](https://avatars.discourse-cdn.com/v4/letter/m/90ced4/32.png) [@martina.gherardi](https://discourse.julialang.org/u/martina.gherardi)\
**Post date:** [November 6, 2023, 9:50pm UTC](https://discourse.julialang.org/t/multiple-solve-same-script/105874/3 "2023-11-06T21:50:03Z")

</div>

@odow Thank you for your answer.

However,  
something doesn’t make sense to me.  
Indeed,  
with steps 1-4 and **without** the explicit warm start, if I write

```julia
set_start_value(some variables not all,GRB_UNDEFINED)

```

I obtain

```julia
No start values specified in MIP start
MIP start from previous solve did not produce a new incumbent solution

```

and then a feasible solution with `Another try with MIP start`.

With step 1-4 and **with** the explicit warm start, depending on the variables I choose to “reset” with GRB\_UNDEFINED, I get different constraints violations.  
For example,

```julia
User MIP start did not produce a new incumbent solution
User MIP start violates constraint R15282 by 64.749216900
MIP start from previous solve did not produce a new incumbent solution

```

Note that the violated constraint R15282 is not one of the constraints I declared, but it is a constraint that jump automatically defines with the warm start.

---

<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 6, 2023, 10:05pm UTC](https://discourse.julialang.org/t/multiple-solve-same-script/105874/4 "2023-11-06T22:05:28Z")

</div>

Because it is closed-source, I don’t have any special insight into how Gurobi chooses to handle start values. Let me see if I can get one of their support people to answer your question.

---

<div class="post-metadata">

**Author:** ![torressa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torressa/32/202204_2.png) [@torressa](https://discourse.julialang.org/u/torressa)\
**Post date:** [November 7, 2023, 9:45am UTC](https://discourse.julialang.org/t/multiple-solve-same-script/105874/5 "2023-11-07T09:45:58Z")

</div>

> With step 1-4 and **with** the explicit warm start, depending on the variables I choose to “reset” with GRB\_UNDEFINED, I get different constraints violations.  
> Note that the violated constraint R15282 is not one of the constraints I declared, but it is a constraint that jump automatically defines with the warm start.

This is a bit weird, can you provide an example of this. I cannot reproduce this easily.

---

<div class="post-metadata">

**Author:** ![martina.gherardi](https://avatars.discourse-cdn.com/v4/letter/m/90ced4/32.png) [@martina.gherardi](https://discourse.julialang.org/u/martina.gherardi)\
**Post date:** [November 7, 2023, 10:40am UTC](https://discourse.julialang.org/t/multiple-solve-same-script/105874/6 "2023-11-07T10:40:00Z")

</div>

@torressa I just sent you an example

---

<div class="post-metadata">

**Author:** ![torressa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torressa/32/202204_2.png) [@torressa](https://discourse.julialang.org/u/torressa)\
**Post date:** [November 7, 2023, 11:43am UTC](https://discourse.julialang.org/t/multiple-solve-same-script/105874/7 "2023-11-07T11:43:01Z")

</div>

Hi Martina, thanks for the example. You are adding new constraints after setting the MIP start, some of which are violated. The constraint names are not read in properly and this leads to the message you are seeing.  
Using `direct_model` when declaring the model seems to help with this.

```julia
MyMod = direct_model(Gurobi.Optimizer())

```

With this, you will see the correct name of the violated constraint in the log.

---

<div class="post-metadata">

**Author:** ![martina.gherardi](https://avatars.discourse-cdn.com/v4/letter/m/90ced4/32.png) [@martina.gherardi](https://discourse.julialang.org/u/martina.gherardi)\
**Post date:** [November 7, 2023, 12:13pm UTC](https://discourse.julialang.org/t/multiple-solve-same-script/105874/8 "2023-11-07T12:13:52Z")

</div>

> [@torressa](#):
>
> `direct_model(Gurobi.Optimizer())`

It works, thank you!

Can you also tell me something about the case **without** the explicit warm start, i.e. the case without

```julia
    var = all_variables(MyMod)
    var_solution = value.(var)
    set_start_value.(var,var_solution)

```

in the code?  
With set\_GRB\_UNDEFINED = 1 (reset of the binaries values), I obtain  
`No start values specified in MIP start`.  
How does the automatic warm start of variables work? Which variables does it choose?  
Note that with set\_GRB\_UNDEFINED = 0, the log does not show violations.

---

<div class="post-metadata">

**Author:** ![torressa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torressa/32/202204_2.png) [@torressa](https://discourse.julialang.org/u/torressa)\
**Post date:** [November 7, 2023, 1:16pm UTC](https://discourse.julialang.org/t/multiple-solve-same-script/105874/9 "2023-11-07T13:16:21Z")

</div>

Perfect!

For a MIP start to be considered it has to be at least a partial MIP start, i.e. you need to set the start values of a subset of variables to a value different to `GRB_UNDEFINED`.  
If you provide a partial MIP start, the rest of the solution will be repaired, see [Start Attribute](https://www.gurobi.com/documentation/current/refman/start.html).

In your example, if you set `set_GRB_UNDEFINED = 1` you will correctly set a partial MIP start as some variables have start values set with

```julia
set_start_value.(var,var_solution)

```

and you reset the start value to `GRB_UNDEFINED` for a subset of them. This leads to the solution being accepted in your example.

---

<div class="post-metadata">

**Author:** ![martina.gherardi](https://avatars.discourse-cdn.com/v4/letter/m/90ced4/32.png) [@martina.gherardi](https://discourse.julialang.org/u/martina.gherardi)\
**Post date:** [November 7, 2023, 1:39pm UTC](https://discourse.julialang.org/t/multiple-solve-same-script/105874/10 "2023-11-07T13:39:04Z")

</div>

I did not explain myself clearly, sorry.

What I meant to say is that I have observed that JuMP automatically does a warm start **without** me writing `set_start_value.(var,var_solution)`.  
The second solve seems to start from an automatic warm start but it is not clear how juMP sets the warm start, which variables considers.

---

<div class="post-metadata">

**Author:** ![torressa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torressa/32/202204_2.png) [@torressa](https://discourse.julialang.org/u/torressa)\
**Post date:** [November 7, 2023, 1:56pm UTC](https://discourse.julialang.org/t/multiple-solve-same-script/105874/11 "2023-11-07T13:56:47Z")

</div>

Oh, thanks for the clarification, I see what you mean!

I think, since we now have a direct model, we are re-optimizing the model after changes. By default, this uses the previous solution as a MIP start (along with a few other things, see [ATTR format](https://www.gurobi.com/documentation/current/refman/attr_format.html) for a complete list).

If you simply call `optimize!` twice you will see something like:

```julia
Continuing optimization...

```
