是否可以在 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能够使用矢量化变量优化用户定义的目标?
首先,使用支持非线性模型的优化器。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)