# Best practice to solve optimization problem repeatedly in a function with MathOptInterface

**URL:** https://discourse.julialang.org/t/best-practice-to-solve-optimization-problem-repeatedly-in-a-function-with-mathoptinterface/23592
**Category:** Optimization (Mathematical)
**Tags:** optimization
**Created:** [April 27, 2019, 7:27am UTC](https://discourse.julialang.org/t/best-practice-to-solve-optimization-problem-repeatedly-in-a-function-with-mathoptinterface/23592 "2019-04-27T07:27:32Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![Yuya-Furusawa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuya-furusawa/32/11585_2.png) [@Yuya-Furusawa](https://discourse.julialang.org/u/Yuya-Furusawa)
#### Post date: [April 27, 2019, 7:27am UTC](https://discourse.julialang.org/t/best-practice-to-solve-optimization-problem-repeatedly-in-a-function-with-mathoptinterface/23592/1 "2019-04-27T07:27:32Z")

</div>

I want to create the function to solve multiple optimization problems with MathOptInterface, such as

```julia
using MathOptInterface
const MOI = MathOptInterface

function opt(optimizer::MOI.AbstractOptimizer)
    ...
    for i in 1:n 
        ...
        x = MOI.add_variables(optimizer, ...)
        MOI.set(optimizer, ...) # scalar affine objective function
        MOI.add_constraints(optimizer, ...) # scalar affine constraint
        MOI.optimize!(optimizer)
        ...
    end
    ...
end

```

I think I have to initialize Optimizer instance in every for loops, but there is no method to do it.

Currently, my code is

```julia
using MathOptInterface
const MOI = MathOptInterface
using GLPK

function opt(mathod::Symbol)
    ...
    for i in 1:n 
        ...
        optimizer = GLPK.Optimizer(method=method) # Only use GLPK optimizer
        x = MOI.add_variables(optimizer, ...)
        MOI.set(optimizer, ...) # scalar affine objective function
        MOI.add_constraints(optimizer, ...) # scalar affine constraint
        MOI.optimize!(optimizer)
        ...
    end
    ...
end

```

However, I don’t want to do hard coding, want to allow the various kinds of solver, such as `Clp.Optimizer` and `CDDLib.Optimizer`.

What is the best practice to do this?

---

<div class="post-metadata">

### Author: ![blegat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/blegat/32/217090_2.png) [@blegat](https://discourse.julialang.org/u/blegat)
#### Post date: [April 27, 2019, 7:47am UTC](https://discourse.julialang.org/t/best-practice-to-solve-optimization-problem-repeatedly-in-a-function-with-mathoptinterface/23592/2 "2019-04-27T07:47:30Z")

</div>

The current recommendation is to ask the user to provide a JuMP.OptimizerFactory with `with_optimizer`.  
Then you get a new instance with `factory()`.  
You could also take an `AbstractOptimizer at argument and call `MOI.empty!` at the start of the function.  
You can find a related discussion here : [https://github.com/JuliaOpt/MathOptInterface.jl/pull/387](https://github.com/JuliaOpt/MathOptInterface.jl/pull/387)

---

<div class="post-metadata">

### Author: ![Yuya-Furusawa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuya-furusawa/32/11585_2.png) [@Yuya-Furusawa](https://discourse.julialang.org/u/Yuya-Furusawa)
#### Post date: [April 27, 2019, 2:10pm UTC](https://discourse.julialang.org/t/best-practice-to-solve-optimization-problem-repeatedly-in-a-function-with-mathoptinterface/23592/3 "2019-04-27T14:10:49Z")

</div>

Thank you!  
But why do you recommend `JuMP.OptimizerFactory` rather than `MOI.empty!` ? Is there any difference in speed or something?

---

<div class="post-metadata">

### Author: ![blegat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/blegat/32/217090_2.png) [@blegat](https://discourse.julialang.org/u/blegat)
#### Post date: [April 27, 2019, 2:21pm UTC](https://discourse.julialang.org/t/best-practice-to-solve-optimization-problem-repeatedly-in-a-function-with-mathoptinterface/23592/4 "2019-04-27T14:21:01Z")

</div>

No difference in speed but `MOI.empty!` don’t work if you want to use several instances of the same solver simultaneously.

---

<div class="post-metadata">

### Author: ![Yuya-Furusawa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuya-furusawa/32/11585_2.png) [@Yuya-Furusawa](https://discourse.julialang.org/u/Yuya-Furusawa)
#### Post date: [April 27, 2019, 3:22pm UTC](https://discourse.julialang.org/t/best-practice-to-solve-optimization-problem-repeatedly-in-a-function-with-mathoptinterface/23592/5 "2019-04-27T15:22:04Z")

</div>

I got the point! I appreciate your kind response!

---

<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: [April 28, 2019, 7:59am UTC](https://discourse.julialang.org/t/best-practice-to-solve-optimization-problem-repeatedly-in-a-function-with-mathoptinterface/23592/6 "2019-04-28T07:59:22Z")

</div>

You don’t have to use `JuMP.OptimizerFactory`. You could just go

```julia
using MathOptInterface
const MOI = MathOptInterface
using GLPK

function opt(factory::Function)
    ...
    for i in 1:n 
        ...
        optimizer = factory()
        x = MOI.add_variables(optimizer, ...)
        MOI.set(optimizer, ...) # scalar affine objective function
        MOI.add_constraints(optimizer, ...) # scalar affine constraint
        MOI.optimize!(optimizer)
        ...
    end
    ...
end

# Then you can call it with
opt(() -> GLPK.Optimizer())

```

---

<div class="post-metadata">

### Author: ![blegat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/blegat/32/217090_2.png) [@blegat](https://discourse.julialang.org/u/blegat)
#### Post date: [April 28, 2019, 12:35pm UTC](https://discourse.julialang.org/t/best-practice-to-solve-optimization-problem-repeatedly-in-a-function-with-mathoptinterface/23592/7 "2019-04-28T12:35:05Z")

</div>

@odow that would work but if it is part of a package, I would recommend using `with_optimizer` to provide a more consistent interface with the rest of the ecosystem
