JuMP 中带有矢量化变量的用户定义(非线性)目标

Kev*_*vin 5 julia julia-jump

是否可以在 JuMP for Julia 中将向量化变量与用户定义的目标函数一起使用?就像这样,

model = Model(GLPK.Optimizer)

A = [
    1 1 9 5
    3 5 0 8
    2 0 6 13
]

b = [7; 3; 5]

c = [1; 3; 5; 2]

@variable(model, x[1:4] >= 0)
@constraint(model, A * x .== b)

# dummy functions, could be nonlinear hypothetically
identity(x) = x
C(x, c) = c' * x

register(model, :identity, 1, identity; autodiff = true)
register(model, :C, 2, C; autodiff = true)
@NLobjective(model, Min, C(identity(x), c))
Run Code Online (Sandbox Code Playgroud)

这会引发错误,

ERROR: Unexpected array VariableRef[x[1], x[2], x[3], x[4]] in nonlinear expression. Nonlinear expressions may contain only scalar expression.
Run Code Online (Sandbox Code Playgroud)

这听起来像是没有。有解决方法吗?我相信scipy.optimize.minimize能够使用矢量化变量优化用户定义的目标?

Prz*_*fel 3

首先,使用支持非线性模型的优化器。GLPK 没有。尝试 Ipopt:

using Ipopt
model = Model(Ipopt.Optimizer)
Run Code Online (Sandbox Code Playgroud)

其次,JuMP 文档如下(参见https://jump.dev/JuMP.jl/stable/manual/nlp/#Syntax-notes):

非线性宏中接受的语法比线性和二次宏的语法更受限制。(...) 所有表达式都必须是简单的标量运算。您不能使用点、矩阵向量积、向量切片等。

你需要包装目标函数

@expression(model, expr,  C(identity(x), c))
Run Code Online (Sandbox Code Playgroud)

现在你可以这样做:

@NLobjective(model, Min, expr)
Run Code Online (Sandbox Code Playgroud)

为了证明它有效,我求解了模型:

julia> optimize!(model)
This is Ipopt version 3.14.4, running with linear solver MUMPS 5.4.1.
...
Total seconds in IPOPT                               = 0.165

EXIT: Optimal Solution Found.

julia> value.(x)
4-element Vector{Float64}:
  0.42307697548737005
  0.3461538282496562
  0.6923076931757742
 -8.46379887234798e-9
Run Code Online (Sandbox Code Playgroud)