最小化向量时如何防止一个值超过向量中的另一个值?

How do I prevent one value from exceeding another value in a vector when minimizing it?

当最小化一个函数时,我试图防止一个值超过所用向量中的另一个值。

例如,这段代码优化了init_x:

using Optim
f(x) = (1.0-x[1])^2+100.0*(-x[2]^2)^2

init_x = [0.0,0.0]
res = Optim.minimizer(Optim.optimize(f, init_x))

哪个returns:

2-element Vector{Float64}:
  0.9999860561511018
 -0.0006072923701139431

如何在优化过程中防止 res 的第一个值 (0.9999860561511018) 超过 res 的第二个值 (-0.0006072923701139431)? 就像使用 res[1] < res[2]

的约束

我建议使用 JuMP,但如果您的模型可以重写您的模型,请将 x[2] 替换为 x[1]+x_[2],其中 x_[2] >=0 并使用框约束优化,例如:

using Optim
f(x) = (1.0-x[1])^2+100.0*(-(x[1]+x[2])^2)^2

init_x = [0.01,0.01]

inner_optimizer = GradientDescent()
result = optimize(f, [-Inf, 0.0],[Inf,Inf], init_x, Fminbox(inner_optimizer))
res = Optim.minimizer(result)

这产生:

julia> final_res=[res[1], res[1]+res[2]]
2-element Vector{Float64}:
 0.16126202305154383
 0.16126202306334733

julia> f([res[1],res[2]])
0.7711096853639534

更通用的解决方案是使用 JuMP

using JuMP, Ipopt
m = Model(optimizer_with_attributes(Ipopt.Optimizer, ("print_level"=>2))); 
@variable(m, x[1:2])

@constraint(m, x[1] <= x[2]  )

@NLobjective(m, Min, (1.0-x[1])^2+100.0*(-x[2]^2)^2)

optimize!(m)

查看结果:

julia> value.(x)
2-element Vector{Float64}:
 0.16126203113215182
 0.16126202262738015

julia> objective_value(m)
0.7711096710776033