Hi,
I’m trying to solve an optimization problem (MI-NLP) where I want certain variables to be integer values. I have tried to get a bunch of different packages/solver to work and landed on Juniper. My code works fine when I ran with only Ipopt, and didn’t use integer-restraints, but when trying to run with Juniper I get the error shown below the code.
using Pkg
using JuMP
using Ipopt
using Juniper
using HiGHS
using Dates
using CSV
using DataFrames
println("--- Start Program ---")
# GENERAL PARAMETERS
tfinal = 8759;
dt = 1; # (h) timestep
years=15;
efficiency_bat = 0.97;
eta_charge = 0.95;
eta_discharge = 0.95;
SOC_bat_MAX = 1; # (-) - Maximum SOC for batteries
SOC_bat_MIN = 0.35; # (-) - Minimum SOC for batteries
# COST PARAMETERS
solar_capex = 668e3; # Capex Solar
solar_opex = 14750*years; # Opex Solar
bat_capex = 630*1000; # Capex Battery
bat_opex = 7400*years; # Opex Battery
wave_capex = 5851275; # Capex OWC
wave_opex = wave_capex*0.05 *years; # Opex OWC
wind_capex = 1200e3;
wind_opex = 150000 * years;
# DEMAND PARAMETERS
demand_t = CSV.read("Demand_data", DataFrame);
# GENERATION PARAMETERS
solar_available = CSV.read("Solar_data", DataFrame);
havkraft = CSV.read("Wave_data", DataFrame);
wind_ = CSV.read("Wind_data", DataFrame);
## INITIAL CONDITIONS
SOC_ini = 0.7; # (p.u) - Initial state of charge of the battery
#model
# Choose underlying solvers for Juniper
ipopt = optimizer_with_attributes(Ipopt.Optimizer, "print_level" => 0)
highs = optimizer_with_attributes(HiGHS.Optimizer, "output_flag" => false)
m = Model(
optimizer_with_attributes(
Juniper.Optimizer,
"nl_solver" => ipopt,
"mip_solver" => highs,
),
)
Juniper.strong
#set_time_limit_sec(m, 800.0)
# Model
## VARIABLES
@variable(m, wind_generation_t[1:tfinal] >= 0) # (MW) wind gen for each time step t
@variable(m, wind_capacity >= 0, Int) # (MWh) wind capacity
@variable(m, wave_generation_t[1:tfinal] >= 0) # (MW) wind gen for each time step t
@variable(m, wave_capacity >= 0, Int) # (MWh) wind capacity
@variable(m, solar_generation_t[1:tfinal] >= 0, Int) # (MW) solar gen for each time step t
@variable(m, solar_capacity >= 0) # (MWh) solar capacity
@variable(m, battery_energy_capacity >= 0, Int) # (MWh) battery capacity
@variable(m, battery_power_capacity >= 0) # (MW) battery capacity
@variable(m, charge_battery_t[1:tfinal] >= 0) # (MW) - Charge power for the battery
@variable(m, discharge_battery_t[1:tfinal] >= 0) # (MW) - Discharge power for the battery
@variable(m, SOC_battery[1:tfinal] >= 0) # (p.u) - State of charge of the battery
# OBJECTIVE FUNCTION
@objective(m, Min, wave_capex + sum(wave_opex*wave_generation_t[1:tfinal]) + wind_capex + sum(wind_opex*wind_generation_t[1:tfinal]) + sum(solar_opex*solar_generation_t[1:tfinal]) + solar_capex + bat_opex*battery_energy_capacity + bat_capex);
# CONSTRAINT 0: WAVE GENERATION FOR ANY HOUR MUST BE LESS THAN MAX CAPACITY
for ti = 1:tfinal
@NLconstraint(m, wave_generation_t[ti] <= wave_capacity);
end
# CONSTRAINT 1: WIND GENERATION FOR ANY HOUR MUST BE LESS THAN MAX CAPACITY
for ti = 1:tfinal
@NLconstraint(m, wind_generation_t[ti] <= wind_capacity);
end
# CONSTRAINT 2: SOLAR GENERATION FOR ANY HOUR MUST BE LESS THAN MAX CAPACITY
for ti = 1:tfinal
@NLconstraint(m, solar_generation_t[ti] <= solar_available[ti,1]);
end
# CONTRAINTS 3: BATTERY CHARGE FOR ANY HOUR MUST BE LESS THAN MAX
for ti = 1:tfinal
@NLconstraint(m, charge_battery_t[ti] <= battery_power_capacity);
end
# COSTRAINT 4: BATTERY DISCHARGE FOR ANY HOUR MUST BE LESS THAN MAX
for ti = 1:tfinal
@NLconstraint(m, discharge_battery_t[ti] <= battery_power_capacity);
end
# CONSTRAINT 5: DISCHARGE CAPACITY IS HALF THE BATTERY POWER CAPACITY
@NLconstraint(m, battery_power_capacity == 0.5*battery_energy_capacity);
# CONSTRAINTS 6: STATE OF CHARGE TRACKING
@NLconstraint(m, SOC_battery[1] == SOC_ini);
for ti = 2:tfinal
@NLconstraint(m, SOC_battery[ti] == SOC_battery[ti-1] + (((eta_charge*charge_battery_t[ti])-(discharge_battery_t[ti]/eta_discharge))*dt)/battery_energy_capacity);
end
# CONSTRAINT 7: DEMAND BALANCING
for ti = 1:tfinal
@NLconstraint(m, wave_capacity*wave_generation_t[ti] + wind_capacity*wind_generation_t[ti] + solar_capacity*solar_generation_t[ti] - charge_battery_t[ti] + discharge_battery_t[ti] == demand_t[ti,1]);
end
# CONSTRAINT 8a: SOC LIMITS (MAXIMUM)
for ti = 1:tfinal
@NLconstraint(m, SOC_bat_MAX >= SOC_battery[ti]);
end
# CONSTRAINT 8b: SOC LIMITS (MINIMUM)
for ti = 1:tfinal
@NLconstraint(m, SOC_battery[ti] >= SOC_bat_MIN);
end
## EXECUTION OF OPTIMIZATION PROBLEM
JuMP.optimize!(m)
When running the code after some time and getting the following outputs
nl_solver : MathOptInterface.OptimizerWithAttributes(Ipopt.Optimizer, Pair{MathOptInterface.AbstractOptimizerAttribute, Any}[MathOptInterface.RawOptimizerAttribute("print_level") => 0])
mip_solver : MathOptInterface.OptimizerWithAttributes(HiGHS.Optimizer, Pair{MathOptInterface.AbstractOptimizerAttribute, Any}[MathOptInterface.RawOptimizerAttribute("output_flag") => false])
log_levels : [:Options, :Table, :Info]
#Variables: 52559
#IntBinVar: 8762
Obj Sense: Min
Start values are not feasible.
Status of relaxation: LOCALLY_SOLVED
Time for relaxation: 388.5899999141693
Relaxation Obj: 8.348895564000039e6
MIPobj NLPobj Time
=============================================
┌ Warning: NLP couldn't be solved to optimality
└ @ Juniper C:\Users\erlen\.julia\packages\Juniper\HBPrQ\src\fpump.jl:405
- - 60.8
FP: 60.78700017929077 s
FP: 1 round
FP: No integral solution found
ONodes CLevel Incumbent BestBound Gap Time Restarts GainGap
============================================================================================================
[ Info: Breaking out of strong branching as the time limit of 100.0 seconds got reached.
1 2 - 8.34889556e6 - 102.3 1 -
2 3 - 8.45989529e6 - 121.7 - 86.7%
3 4 - 8.45989528e6 - 139.6 - 51.4%
4 5 - 8.45989528e6 - 157.3 - 78.5%
5 6 - 8.45989528e6 - 174.8 - 86.2%
6 7 - 8.45989528e6 - 192.9 - 79.3%
7 8 - 8.45989528e6 - 209.9 - 90.3%
8 9 - 8.45989528e6 - 227.0 - 91.2%
9 10 - 8.45989528e6 - 245.0 - 64.3%
10 11 - 8.45989528e6 - 262.3 - 96.7%
11 12 - 8.45989528e6 - 279.2 - 93.5%
12 13 - 8.45989528e6 - 297.7 - 74.7%
13 14 - 8.45989528e6 - 314.5 - 98.7% ^C
14 15 - 8.45989528e6 - 330.8 - 71.3%
The following error occurs. What am I doing wrong?
ERROR: InterruptException:
Stacktrace:
[1] try_yieldto(undo::typeof(Base.ensure_rescheduled))
@ Base .\task.jl:920
[2] wait()
@ Base .\task.jl:984
[3] uv_write(s::Base.TTY, p::Ptr{UInt8}, n::UInt64)
@ Base .\stream.jl:1048
[4] unsafe_write(s::Base.TTY, p::Ptr{UInt8}, n::UInt64)
@ Base .\stream.jl:1120
[5] write
@ .\strings\io.jl:244 [inlined]
[6] print(io::Base.TTY, s::String)
@ Base .\strings\io.jl:246
[7] print(::Base.TTY, ::String, ::String, ::Vararg{Any})
@ Base .\strings\io.jl:46
[8] println(::Base.TTY, ::String, ::Vararg{Any})
@ Base .\strings\io.jl:75
[9] println(xs::String)
@ Base .\coreio.jl:4
[10] #print_table#49
@ C:\Users\erlen\.julia\packages\Juniper\HBPrQ\src\table_log.jl:80 [inlined]
[11] print_table
@ C:\Users\erlen\.julia\packages\Juniper\HBPrQ\src\table_log.jl:60 [inlined]
[12] solve_sequential(tree::Juniper.BnBTreeObj, last_table_arr::Vector{Any}, time_bnb_solve_start::Float64, fields::Vector{Symbol}, field_chars::Vector{Int64}, time_obj::Juniper.TimeObj)
@ Juniper C:\Users\erlen\.julia\packages\Juniper\HBPrQ\src\BnBTree.jl:496
[13] solvemip(tree::Juniper.BnBTreeObj)
@ Juniper C:\Users\erlen\.julia\packages\Juniper\HBPrQ\src\BnBTree.jl:743
[14] optimize!(model::Juniper.Optimizer)
@ Juniper C:\Users\erlen\.julia\packages\Juniper\HBPrQ\src\MOI_wrapper\MOI_wrapper.jl:356
[15] optimize!
@ C:\Users\erlen\.julia\packages\MathOptInterface\wW7fs\src\Bridges\bridge_optimizer.jl:378 [inlined]
[16] optimize!
@ C:\Users\erlen\.julia\packages\MathOptInterface\wW7fs\src\MathOptInterface.jl:85 [inlined]
[17] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{Juniper.Optimizer}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}})
@ MathOptInterface.Utilities C:\Users\erlen\.julia\packages\MathOptInterface\wW7fs\src\Utilities\cachingoptimizer.jl:316
[18] optimize!(model::Model; ignore_optimize_hook::Bool, _differentiation_backend::MathOptInterface.Nonlinear.SparseReverseMode, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ JuMP C:\Users\erlen\.julia\packages\JuMP\D44Aq\src\optimizer_interface.jl:448
[19] optimize!(model::Model)
@ JuMP C:\Users\erlen\.julia\packages\JuMP\D44Aq\src\optimizer_interface.jl:409
[20] top-level scope
@ c:\Users\erlen\OneDrive\Bilder\Dokumenter\UPC\EnergyStorage\Project\masterOpt.jl:131