SDDiP.jl - LoadError: AssertionError: [...] == :Optimal

Hi all,

I’m new to Julia (coming from AMPL), and I’m trying to solve a model using the SDDiP algorithm implemented in SDDiP.jl and CPLEX.

I’m able to implement many of the example models, and the algorithm generally works fine for my model. However, I’ve noticed that occasionally I am getting an error after many iterations (e.g., after 165 iterations).

Warning: Not solved to optimality, status: CPX_STAT_OPTIMAL_INFEAS
ERROR: LoadError: AssertionError: JuMP.solve(sp, ignore_solve_hook=true, relaxation=true) == :Optimal
Stacktrace:
 [1] #SDDiPsolve!#2(::Bool, ::Int64, ::Array{Any,1}, ::Function, ::JuMP.Model) at C:\Users\ELTUCK\.julia\v0.6\SDDiP\src\solver.jl:73
 [2] (::SDDiP.#kw##SDDiPsolve!)(::Array{Any,1}, ::SDDiP.#SDDiPsolve!, ::JuMP.Model) at .\<missing>:0
 [3] #solve#133(::Bool, ::Bool, ::Bool, ::Array{Any,1}, ::Function, ::JuMP.Model) at C:\Users\ELTUCK\.julia\v0.6\JuMP\src\solvers.jl:151
 [4] (::JuMP.#kw##solve)(::Array{Any,1}, ::JuMP.#solve, ::JuMP.Model) at .\<missing>:0
 [5] JuMPsolve at C:\Users\ELTUCK\.julia\v0.6\SDDiP\src\solver.jl:8 [inlined]
 [6] solvesubproblem!(::Type{SDDP.BackwardPass}, ::SDDP.SDDPModel{SDDP.DefaultValueFunction{SDDP.DefaultCutOracle}}, ::JuMP.Model, ::Float64) at C:\Users\ELTUCK\.julia\v0.6\SDDP\src\defaultvaluefunction.jl:146
 [7] backwardpass!(::SDDP.SDDPModel{SDDP.DefaultValueFunction{SDDP.DefaultCutOracle}}, ::SDDP.Settings) at C:\Users\ELTUCK\.julia\v0.6\SDDP\src\SDDP.jl:239
 [8] macro expansion at C:\Users\ELTUCK\.julia\v0.6\SDDP\src\SDDP.jl:278 [inlined]
 [9] macro expansion at C:\Users\ELTUCK\.julia\v0.6\TimerOutputs\src\TimerOutput.jl:177 [inlined]
 [10] iteration!(::SDDP.SDDPModel{SDDP.DefaultValueFunction{SDDP.DefaultCutOracle}}, ::SDDP.Settings) at C:\Users\ELTUCK\.julia\v0.6\SDDP\src\SDDP.jl:277
 [11] macro expansion at C:\Users\ELTUCK\.julia\v0.6\SDDP\src\SDDP.jl:317 [inlined]
etc.

I am not exactly sure how to proceed. I am not sure if this indicates an issue with the tolerance parameters or the formulation (or something else entirely).

Does anyone have suggestions on handling this type of error?

Versions (not updated to newest so that they’re consistent with the SDDiP code)
Julia: 0.6.4
JuMP: 0.18.5
CPLEX: 0.4.2
GLPKMathProgInterface: 0.4.4

Thank you,
Emily

CPX_STAT_OPTIMAL_INFEAS means that CPLEX did not successfully solve the problem to the requested tolerances. (It found an “optimal” solution which became infeasible after inverting presolve reductions.) This status doesn’t indicate that there’s anything wrong with the formulation, although it could perhaps be numerically challenging.

You could tweak the code to ignore this specific status and continue or adjust the tolerances and try again. @lkapelevich may be able to advise on what to do specifically for SDDiP.jl.

Hey Emily,

I don’t have advice of the top of my head. It may be helpful to play around with SDDP’s cut selection if you haven’t already.

I’m sorry you’re stuck on old software :-(. On that note @odow any updates on advice for overloading duals in SDDP?

Thank you both! This is helpful.

Hi @eltuck

The lead cause of these sorts of error is problem scaling. See:
https://odow.github.io/SDDP.jl/latest/tutorial/06_warnings/#Numerical-stability-1

In general, I’ve found Gurobi to be more reliable when it comes to numerical issues like this, but it also tends to be a little slower. I advise that you try it out to see if it works for your problem.

@lkapelevich let’s continue the discussion here: https://github.com/odow/SDDP.jl/issues/195#issuecomment-499096062

Thank you @odow! I’ll look further into problem scaling and give Gurobi a try.

1 Like

Hi,
if I use the expression with SDDP package as follows,

function subproblem_builder(subproblem::Model,node::Int)
    .............
    return subproblem
end

Can I know the detailed information of “subproblem” . Now the results returned only tell me “subproblem_builder (generic function with 1 method)”. I want to know how much or the structure of variables,constraints,and stageobjective in my subproblem
Thanks in advance!

Please open a new thread, rather than continuing this one.

The function just helps build the model. You need to call SDDP.PolicyGraph to actually construct it.

Thank you very much for your reply. I have tried “LinearPolicyGraph”. However, when I write

model = SDDP.LinearPolicyGraph(
    stages = 3,
    sense = :Min,
    lower_bound = 0.0,
    optimizer = Gurobi.Optimizer,
) do subproblem, node
@variables....
@constraints.....
@stageobjective.....
end

Only the “a policy graph with 3 nodes,Nodes indices: 1,2,3”, can be got.
I still cannot see the variables,constraints,stageobjective included in my model?

print(model[1].subproblem)

But again, please open a new thread if you have more questions. This isn’t related to the original post, and it makes it harder for future people searching for related questions.

Ok,Thanks a lot!