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

我已经成功介绍了问题的基础:

数学表达:

变量范围不能包含其他变量。做:

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])