# SDDP: how to use Juniper.jl for optimizer

**URL:** https://discourse.julialang.org/t/sddp-how-to-use-juniper-jl-for-optimizer/82719
**Category:** Optimization (Mathematical)
**Created:** [June 14, 2022, 2:00am UTC](https://discourse.julialang.org/t/sddp-how-to-use-juniper-jl-for-optimizer/82719 "2022-06-14T02:00:06Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![chenr86](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chenr86/32/36785_2.png) [@chenr86](https://discourse.julialang.org/u/chenr86)
#### Post date: [June 14, 2022, 2:00am UTC](https://discourse.julialang.org/t/sddp-how-to-use-juniper-jl-for-optimizer/82719/1 "2022-06-14T02:00:06Z")

</div>

Hello,

I’m trying to solve MI-NLP problem with `SDDP.jl.` I would like to use `juniper.jl` as optimizer:

```julia
using SDDP 
using Ipopt
using Juniper

nl_solver = optimizer_with_attributes(Ipopt.Optimizer, "print_level"=>0)
minlp_solver = optimizer_with_attributes(Juniper.Optimizer, "nl_solver"=>nl_solver)
# model = Model(minlp_solver)

# Building the subproblem
model = SDDP.LinearPolicyGraph(
    stages = numtime,
    sense = :Min,
    lower_bound = 0.0,
    optimizer = minlp_solver,
) do sp, node
...
end

```

But when I train the model, I got error saying:

```julia
ArgumentError: MathOptInterface.Utilities.Model{Float64} does not support getting the attribute MathOptInterface.ConstraintDual(1).

Stacktrace:
  [1] get_fallback(model::MathOptInterface.Utilities.Model{Float64}, attr::MathOptInterface.ConstraintDual, #unused#::MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.EqualTo{Float64}})
    @ MathOptInterface ~/.julia/packages/MathOptInterface/RuRWI/src/attributes.jl:367
  [2] get(model::MathOptInterface.Utilities.Model{Float64}, attr::MathOptInterface.ConstraintDual, args::MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.EqualTo{Float64}})
    @ MathOptInterface ~/.julia/packages/MathOptInterface/RuRWI/src/attributes.jl:336
  [3] get(uf::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}, attr::MathOptInterface.ConstraintDual, ci::MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.EqualTo{Float64}})
    @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/RuRWI/src/Utilities/universalfallback.jl:393
  [4] get(model::Juniper.Optimizer, attr::MathOptInterface.ConstraintDual, ci::MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.EqualTo{Float64}})
    @ Juniper ~/.julia/packages/Juniper/0Z1vO/src/MOI_wrapper/MOI_wrapper.jl:474
  [5] get(b::MathOptInterface.Bridges.LazyBridgeOptimizer{Juniper.Optimizer}, attr::MathOptInterface.ConstraintDual, ci::MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.EqualTo{Float64}})
    @ MathOptInterface.Bridges ~/.julia/packages/MathOptInterface/RuRWI/src/Bridges/bridge_optimizer.jl:1303
  [6] get(model::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{Juniper.Optimizer}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}, attr::MathOptInterface.ConstraintDual, index::MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.EqualTo{Float64}})

```

How can I specify juniper solver appropriately with `SDDP.jl`?

---

<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: [June 14, 2022, 2:53am UTC](https://discourse.julialang.org/t/sddp-how-to-use-juniper-jl-for-optimizer/82719/2 "2022-06-14T02:53:47Z")

</div>

SDDP.jl isn’t the right tool to use for solving a MINLP. It’s mainly intended for multistage stochastic _linear_ problems.

There’s limited support for continuous nonlinear convex problems, for which you can use Ipopt. There’s also some limited support for integer linear problems, for which you should use Gurobi or HiGHS.

But there is no support for MINLP.

---

<div class="post-metadata">

### Author: ![chenr86](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chenr86/32/36785_2.png) [@chenr86](https://discourse.julialang.org/u/chenr86)
#### Post date: [June 14, 2022, 3:32am UTC](https://discourse.julialang.org/t/sddp-how-to-use-juniper-jl-for-optimizer/82719/3 "2022-06-14T03:32:06Z")

</div>

whenever there are multiplication, square root or division, constraints or objectives should be posted as nonlinear?

One of my constraints is defined as (using `SDDP.jl`):

```julia
@NLconstraint(
        sp, 
        flow == (0.685 - 0.19 * n * 0.05 / (level.in - 261)) * 0.5 * n * sqrt(2 * 9.81 * (level.in - 261))
    )

```

---

<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: [June 14, 2022, 3:42am UTC](https://discourse.julialang.org/t/sddp-how-to-use-juniper-jl-for-optimizer/82719/4 "2022-06-14T03:42:48Z")

</div>

You might want to revisit the theory behind SDDP.jl: [Introductory theory · SDDP.jl](https://odow.github.io/SDDP.jl/stable/tutorial/theory/21_theory_intro/)

It approximates **convex** functions, so things like `1 / level.in` and `sqrt(level.in)` or nonlinear equality constraints will **not** work.

SDDP.jl lets you formulate nonlinear models, because in some cases you can formulates and solve convex nonlinear problems, but if you write a non-convex constraint, SDDP.jl will give you a suboptimal answer. If you don’t have integer variables, try solving it with Ipopt, but there is no guarantees on what could go wrong. If you do have integer variables, consider a different solution technique.

As a side note: dealing with head effects in hydro-thermal scheduling is an open question in the literature. A few different solutions have been proposed, but no SDDP-type algorithms adequately deal with the non-convexities. In general, you could consider training on a convex approximation, but then simulate with the non-convexities, but explaining how to do this is quite complicated and probably outside the scope of this forum. It’d be a research/engineering paper in and of itself.

---

<div class="post-metadata">

### Author: ![chenr86](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chenr86/32/36785_2.png) [@chenr86](https://discourse.julialang.org/u/chenr86)
#### Post date: [June 14, 2022, 3:47am UTC](https://discourse.julialang.org/t/sddp-how-to-use-juniper-jl-for-optimizer/82719/5 "2022-06-14T03:47:17Z")

</div>

Thanks! I will not use integer variable in my case.

---

<div class="post-metadata">

### Author: ![chenr86](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chenr86/32/36785_2.png) [@chenr86](https://discourse.julialang.org/u/chenr86)
#### Post date: [June 15, 2022, 1:17am UTC](https://discourse.julialang.org/t/sddp-how-to-use-juniper-jl-for-optimizer/82719/6 "2022-06-15T01:17:44Z")

</div>

Despite of `SDDP.jl`, is there any other package supported to solve multistage dynamic programming and also MINLP? In my case, I don’t really care about stochasticity, the main issue is about **multistage**.

---

<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: [June 15, 2022, 1:33am UTC](https://discourse.julialang.org/t/sddp-how-to-use-juniper-jl-for-optimizer/82719/7 "2022-06-15T01:33:42Z")

</div>

If you have a deterministic time-staged MINLP, why not just formulate it as a single large MINLP? Time-staged decomposition methods don’t work well for MINLP due to the non-convexity.

---

<div class="post-metadata">

### Author: ![chenr86](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chenr86/32/36785_2.png) [@chenr86](https://discourse.julialang.org/u/chenr86)
#### Post date: [June 15, 2022, 1:45am UTC](https://discourse.julialang.org/t/sddp-how-to-use-juniper-jl-for-optimizer/82719/8 "2022-06-15T01:45:21Z")

</div>

Well, I attempt to formulate my problem as a single large MINLP at the beginning. But it seems to be a little complicated, so I turn to SDDP.jl

---

<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 10, 2025, 8:02pm UTC](https://discourse.julialang.org/t/sddp-how-to-use-juniper-jl-for-optimizer/82719/9 "2025-04-10T20:02:23Z")

</div>

6 posts were split to a new topic: [Convergence of SDDP with nonlinear objective and mixed-integer variables](https://discourse.julialang.org/t/convergence-of-sddp-with-nonlinear-objective-and-mixed-integer-variables/127947)
