Julia:如何为 JuMP 的混合整数优化问题引入二进制整数?
Julia: How to introduce binary integers for mixed integers optimization problems with JuMP?
Problem description
我正在尝试使用 Jump 对 Julia 中的“单元承诺”问题进行混合整数优化。但是 JuMP 希望我引入的 unit activation 变量 x[1:N]
是一个数字而不是变量。但是,unit activation 是优化问题的二进制整数决策变量,因此我无法将变量包含在优化问题中。
我做错了什么?
我的方法是:
Approach 1: Include x[1:N]
as part of @variable
macro for P_G
.
m = Model(Cbc.Optimizer) # Model
@variable(m, x[1:N], Bin) # Unit activation
@variable(m, P_C[i,1]*x[i] <= P_G[i=1:N,1:T] <= P_C[i,2]*x[i]) # Unit generation limit
for i in 1:T # Load balance
@constraint(m, sum(P_G[:,i]) == P_D[i])
end
@objective(m,Min,sum(P_G[:,1:T].*F[1:N]*x[1:N])) # Objective function
optimize!(m) # Solve
这会导致以下错误:
LoadError: InexactError: convert(Float64, 50 x[1])
.
Approach 2: Define the feasible region for P_G
as a constraint including x[1:N]
:
m = Model(Cbc.Optimizer) # Model
@variable(m, x[1:N]) # Unit activation
@variable(m, P_G[i=1:N,1:T] ) # Unit generation limit
for i in 1:T # Load balance
@constraint(m, sum(P_G[:,i]) == P_D[i])
end
for i in 1:N # Unit generation limit
for j in 1:T
@constraint(m, P_C[i,1]*x[i] <= P_G[i,j] <= P_C[i,2]*x[i])
end
end
@objective(m,Min,sum(P_G[:,1:T].*F[1:N]*x[1:N])) # Objective function
optimize!(m) # Solve
这导致:LoadError: [..] '@constraint(m, $(Expr(:escape, :(P_C[i, 1]))) * $(Expr(:escape, :(x[i]))) <= P_G[i, j] <= $(Expr(:escape, :(P_C[i, 2]))) * $(Expr(:escape, :(x[i]))))': Expected 50 x[1] to be a number.
注意:可能有更合适的迭代方法,但这对像我这样的 Julia 和 JuMP 新手来说应该是白痴证明。
Working code without mixed-integer optimization
using JuMP, Cbc # Optimization and modelling
using Plots, LaTeXStrings # Plotting
# DATA
P_C = [50 200; # Power capacity [:, (min, max)]
25 200;
100 200;
120 500;
10 500;
20 500;
200 800;
200 800;
100 800;
200 1000;]
P_D = LinRange(sum(P_C[:,1]), sum(P_C[:,2]), 100) # Power demand
F = rand(100:500,10) # Random prod. prices
T = length(P_D) # Number of time steps
N = length(P_C[:,1]) # Number of generators
# MODEL
m = Model(Cbc.Optimizer) # Model
@variable(m, x[1:N], Bin) # Unit activation
@variable(m, P_C[i,1] <= P_G[i=1:N,1:T] <= P_C[i,2]) # Unit generation limit
for i in 1:T # Load balance
@constraint(m, sum(P_G[:,i]) == P_D[i])
end
@objective(m,Min,sum(P_G[:,1:T].*F[1:N])) # Objective function
optimize!(m) # Solve
# PLOT
plt = plot(P_D[:],value.(P_G[:,1:T])', xlab = L"P_{load} [MW]", ylab = L"P_{unit} [MW]")
@show plt
应该会产生类似的东西:
引入单元激活变量的预期结果是每个单元都不需要在 P_load
的下部区域发电。
Preliminary
我已经成功介绍了问题的基础:
- Objective功能:最大限度降低发电成本
- 可变,
P_G
:用于发电(由最小和最大容量定义的可行区域,P_C
)
- 生产成本,
F
(仅保持不变!)
- 功率需求
P_D
设置为与最小功率上限成线性关系 space。达到最大上限。
数学表达:
变量范围不能包含其他变量。做:
m = Model(Cbc.Optimizer)
@variable(m, x[1:N], Bin)
@variable(m, P_G[i=1:N,1:T])
@constraint(m, [i=1:N, t=1:T], P_C[i, 1] * x[i] <= P_G[i, t])
@constraint(m, [i=1:N, t=1:T], P_G[i, t] <= P_C[I, 2] * x[i])
Problem description
我正在尝试使用 Jump 对 Julia 中的“单元承诺”问题进行混合整数优化。但是 JuMP 希望我引入的 unit activation 变量 x[1:N]
是一个数字而不是变量。但是,unit activation 是优化问题的二进制整数决策变量,因此我无法将变量包含在优化问题中。
我做错了什么?
我的方法是:
Approach 1: Include
x[1:N]
as part of@variable
macro forP_G
.
m = Model(Cbc.Optimizer) # Model
@variable(m, x[1:N], Bin) # Unit activation
@variable(m, P_C[i,1]*x[i] <= P_G[i=1:N,1:T] <= P_C[i,2]*x[i]) # Unit generation limit
for i in 1:T # Load balance
@constraint(m, sum(P_G[:,i]) == P_D[i])
end
@objective(m,Min,sum(P_G[:,1:T].*F[1:N]*x[1:N])) # Objective function
optimize!(m) # Solve
这会导致以下错误:
LoadError: InexactError: convert(Float64, 50 x[1])
.
Approach 2: Define the feasible region for
P_G
as a constraint includingx[1:N]
:
m = Model(Cbc.Optimizer) # Model
@variable(m, x[1:N]) # Unit activation
@variable(m, P_G[i=1:N,1:T] ) # Unit generation limit
for i in 1:T # Load balance
@constraint(m, sum(P_G[:,i]) == P_D[i])
end
for i in 1:N # Unit generation limit
for j in 1:T
@constraint(m, P_C[i,1]*x[i] <= P_G[i,j] <= P_C[i,2]*x[i])
end
end
@objective(m,Min,sum(P_G[:,1:T].*F[1:N]*x[1:N])) # Objective function
optimize!(m) # Solve
这导致:LoadError: [..] '@constraint(m, $(Expr(:escape, :(P_C[i, 1]))) * $(Expr(:escape, :(x[i]))) <= P_G[i, j] <= $(Expr(:escape, :(P_C[i, 2]))) * $(Expr(:escape, :(x[i]))))': Expected 50 x[1] to be a number.
注意:可能有更合适的迭代方法,但这对像我这样的 Julia 和 JuMP 新手来说应该是白痴证明。
Working code without mixed-integer optimization
using JuMP, Cbc # Optimization and modelling
using Plots, LaTeXStrings # Plotting
# DATA
P_C = [50 200; # Power capacity [:, (min, max)]
25 200;
100 200;
120 500;
10 500;
20 500;
200 800;
200 800;
100 800;
200 1000;]
P_D = LinRange(sum(P_C[:,1]), sum(P_C[:,2]), 100) # Power demand
F = rand(100:500,10) # Random prod. prices
T = length(P_D) # Number of time steps
N = length(P_C[:,1]) # Number of generators
# MODEL
m = Model(Cbc.Optimizer) # Model
@variable(m, x[1:N], Bin) # Unit activation
@variable(m, P_C[i,1] <= P_G[i=1:N,1:T] <= P_C[i,2]) # Unit generation limit
for i in 1:T # Load balance
@constraint(m, sum(P_G[:,i]) == P_D[i])
end
@objective(m,Min,sum(P_G[:,1:T].*F[1:N])) # Objective function
optimize!(m) # Solve
# PLOT
plt = plot(P_D[:],value.(P_G[:,1:T])', xlab = L"P_{load} [MW]", ylab = L"P_{unit} [MW]")
@show plt
应该会产生类似的东西:
引入单元激活变量的预期结果是每个单元都不需要在 P_load
的下部区域发电。
Preliminary
我已经成功介绍了问题的基础:
- Objective功能:最大限度降低发电成本
- 可变,
P_G
:用于发电(由最小和最大容量定义的可行区域,P_C
) - 生产成本,
F
(仅保持不变!) - 功率需求
P_D
设置为与最小功率上限成线性关系 space。达到最大上限。
数学表达:
变量范围不能包含其他变量。做:
m = Model(Cbc.Optimizer)
@variable(m, x[1:N], Bin)
@variable(m, P_G[i=1:N,1:T])
@constraint(m, [i=1:N, t=1:T], P_C[i, 1] * x[i] <= P_G[i, t])
@constraint(m, [i=1:N, t=1:T], P_G[i, t] <= P_C[I, 2] * x[i])