How to understand the optimization behavior JuMP?

Hi, I am new to Julia and JuMP package. Recently I am trying to use JuMP
to solve similar optimization problems like Power Systems posted in JuMP’s tutorial.
I read through the page, find the section unit commitment is amazing! Following is the code from
the JuMP website:

using JuMP
import DataFrames
import GLPK
import Plots
import StatsPlots
function ThermalGenerator(
min::Float64,
max::Float64,
fixed_cost::Float64,
variable_cost::Float64,
)
return (
min = min,
max = max,
fixed_cost = fixed_cost,
variable_cost = variable_cost,
)
end

generators = [
ThermalGenerator(0.0, 1000.0, 1000.0, 50.0),
ThermalGenerator(300.0, 1000.0, 0.0, 100.0),
]
WindGenerator(variable_cost::Float64) = (variable_cost = variable_cost,)

wind_generator = WindGenerator(50.0)
function Scenario(demand::Float64, wind::Float64)
return (demand = demand, wind = wind)
end

scenario = Scenario(1500.0, 200.0)
function solve_uc(generators::Vector, wind, scenario)
uc = Model(GLPK.Optimizer)
N = length(generators)
@variable(uc, generators[i].min <= g[i = 1:N] <= generators[i].max)
@variable(uc, 0 <= w <= scenario.wind)
@constraint(uc, sum(g[i] for i in 1:N) + w == scenario.demand)
# !!! New: add binary on-off variables for each generator
@variable(uc, u[i = 1:N], Bin)
@constraint(uc, [i = 1:N], g[i] <= generators[i].max * u[i])
@constraint(uc, [i = 1:N], g[i] >= generators[i].min * u[i])
@objective(
uc,
Min,
sum(generators[i].variable_cost * g[i] for i in 1:N) +
wind.variable_cost * w +
# !!! new
sum(generators[i].fixed_cost * u[i] for i in 1:N)
)
optimize!(uc)
status = termination_status(uc)
if status != OPTIMAL
return (status = status,)
end
return (
status = status,
g = value.(g),
w = value(w),
wind_spill = scenario.wind - value(w),
u = value.(u),
total_cost = objective_value(uc),
)
end

solution = solve_uc(generators, wind_generator, scenario)

println("Dispatch of Generators: “, solution.g, " MW”)
println("Commitments of Generators: ", solution.u)
println("Dispatch of Wind: “, solution.w, " MW”)
println("Wind spillage: “, solution.wind_spill, " MW”)
println(“Total cost: $”, solution.total_cost)

Here, the unit commit is achieved by introducing the binary variable u.
Can we think of this case as a mix-integer optimization problem? So JuMP can be directly used to
solve a mix-integer optimization problem? Because I was expecting a mix-integer solve to solve this kind of problem where the decision variables include integer and real numbers (float).
Thank you very much for your time!

Yes? I mean there are binary and continuous variables. And both are relevant to the solution (will not be optimized out).

What exactly do you mean by that? JuMP is an abstraction layer that allow you to create mathematical models and then choose between many solvers available changing just one or two lines. JuMP does not solve anything by itself, in this example it is using the GLPK solver to do the optimization.

1 Like

Yes. I see. I will check more with the GLPK solver. Thanks!

I can already say to you that GLPK is open source, automatically installed, and, in general, a great choice for toy models. But for really big models, you want an academic license of either Gurobi, CPLEX, or Xpress. For these you need a commercial or academic license from their official site. I use Gurobi, so each 2~3 months I need to call a command from inside my university’s network with a new license code that I get from their site to re-validate the Gurobi installation in my machine.

1 Like

Thank you for the information! I think I will need more powerful solvers. I have installed Gurobi and CPLEX with academic licenses.

1 Like