使用平等和不平等约束
|
该页面正在翻译中。 |
多个优化包可与MathOptInterface和Optim的 IPNewton 求解器可以处理非线性约束。 优化。jl提供了一个简单的接口来将约束定义为Julia函数,然后在 优化功能 指示它是平等还是不等式约束。
让我们将rosenbrock函数定义为我们的目标函数,并将以下不等式视为我们的约束。
using Optimization, OptimizationMOI, OptimizationOptimJL, Ipopt
using ForwardDiff, ModelingToolkit
rosenbrock(x, p) = (p[1] - x[1])^2 + p[2] * (x[2] - x[1]^2)^2
x0 = zeros(2)
_p = [1.0, 1.0]
2-element Vector{Float64}:
1.0
1.0
接下来,我们将平方和与优化变量的乘积定义为约束函数。
cons(res, x, p) = (res .= [x[1]^2 + x[2]^2, x[1] * x[2]])
cons (generic function with 1 method)
我们将使用 IPNewton 来自Optim的求解器来解决问题。
optprob = OptimizationFunction(rosenbrock, Optimization.AutoForwardDiff(), cons = cons)
prob = OptimizationProblem(optprob, x0, _p, lcons = [-Inf, -1.0], ucons = [0.8, 2.0])
sol = solve(prob, IPNewton())
retcode: Success
u: 2-element Vector{Float64}:
0.7519644536194577
0.484303066780286
让我们检查约束是否满足,目标是否低于初始值。
res = zeros(2)
cons(res, sol.u, _p)
res
2-element Vector{Float64}:
0.7999999999999997
0.36417869099766553
prob.f(sol.u, _p)
0.06810654459826093
我们也可以将Ipopt库与OptimizationMOI包一起使用。
sol = solve(prob, Ipopt.Optimizer())
retcode: Success
u: 2-element Vector{Float64}:
0.7519644519971305
0.4843030638909282
res = zeros(2)
cons(res, sol.u, _p)
res
2-element Vector{Float64}:
0.7999999947614852
0.3641786880392731
prob.f(sol.u, _p)
0.06810654547600103
我们也可以使用ModelingToolkit作为我们的广告后端,并为目标和约束生成符号导数和表达式图。
让我们修改边界以将函数用作相等约束。 约束现在变成 -
optprob = OptimizationFunction(rosenbrock, Optimization.AutoSymbolics(), cons = cons)
prob = OptimizationProblem(optprob, x0, _p, lcons = [1.0, 0.5], ucons = [1.0, 0.5])
OptimizationProblem. In-place: true
u0: 2-element Vector{Float64}:
0.0
0.0
下面,AmplNLWriter。jl包用于使用Ipopt库来解决问题。
using AmplNLWriter, Ipopt_jll
sol = solve(prob, AmplNLWriter.Optimizer(Ipopt_jll.amplexe))
retcode: Default
u: 2-element Vector{Float64}:
NaN
NaN
约束条件如预期的那样分别评估为1.0和0.5。
res = zeros(2)
cons(res, sol.u, _p)
println(res)
[NaN, NaN]