Unable to retrieve solution after solving JuMP model

I have a large code that solves an optimization model. To keep the code clean I am trying to move the part that calls the optimizer and retrieve solution to a separate function. Even though I am able to solve the model this way, but retrieving the solution throws an error (ERROR: LoadError: NoOptimizer()). An MWE is provided below:

function defineAndSolveModel()
    
    model = Model()
    
    @variables(model, begin
        y1<=0
        y2<=0
        y3
    end)
    
    
    @constraint(model, con1, y1 + 2*y3 <= 3)
    @constraint(model, con2, -2*y1 + y2- 3*y3 == 2)
    @constraint(model, con3, 3*y1 + 3*y2- 7*y3 == -3)
    @constraint(model, con4, 4*y1 - 4*y3 >= 4)
    
    
    
    @objective(model, Max, 3*y1 - 5*y2 - 2*y3)

    solution = solveModel(model)

    return solution 

end

function solveModel(model)
    println(all_variables(model)) # prints VariableRef[y1, y2, y3]
    
    set_optimizer(model, CPLEX.Optimizer) 
    optimize!(model)  #The model solves successfully

    #The two lines below throw error
    sol = (value.(y1), value.(y2), value.(y3)) 
    dualVars = (dual.(con1), dual.(con2), dual.(con3), dual.(con4))

    return objective_value(model), sol, dualVars
end

defineAndSolveModel()

Can someone point out the issue here? Thank you.

The y variables and con constraints are not defined in the function solveModel. You must have separate variables defined in your REPL that are missing a solver.

Option 1: use model[:y1] and model[:con1] to get the values.

function solveModel(model)
    set_optimizer(model, CPLEX.Optimizer) 
    optimize!(model)
    y1, y2, y3 = model[:y1], model[:y2], model[:y3]
    con1, con2, con3, con4 = model[:con1], model[:con2], model[:con3], model[:con4]
    sol = (value.(y1), value.(y2), value.(y3)) 
    dualVars = (dual.(con1), dual.(con2), dual.(con3), dual.(con4))
    return objective_value(model), sol, dualVars
end

Option 2: pass to solveModel

solution = solveModel(model, [y1, y2, y3], [con1, con2, con3, con4])

function solveModel(model, y, con)
    set_optimizer(model, CPLEX.Optimizer) 
    optimize!(model)
    return objective_value(model), value.(y), dual.(con)
end

Here is more documentation:
https://jump.dev/JuMP.jl/stable/variables/#What-is-a-JuMP-variable?-1
https://jump.dev/JuMP.jl/stable/constraints/#The-@constraint-macro-1

3 Likes

This works. Thank you!

1 Like