将 MATLAB 优化函数转换为 julia
convert MATLAB optimise function to julia
我正在尝试将 Matlab fmincon 优化函数转换为 julia。
但运气不佳。
我觉得可以用NLopt或者IPopt。
默认示例有效,但当我尝试更改值时,它似乎没有重复。
using NLopt
count = 0 # keep track of # function evaluations
function myfunc(x::Vector, grad::Vector)
if length(grad) > 0
grad[1] = 0
grad[2] = 0.5/sqrt(x[2])
end
global count
count::Int += 1
println("f_$count($x)")
sqrt(x[2])
end
function myconstraint(x::Vector, grad::Vector, a, b)
if length(grad) > 0
grad[1] = 3a * (a*x[1] + b)^2
grad[2] = -1
end
(a*x[1] + b)^3 - x[2]
end
opt = Opt(:LD_MMA, 2)
lower_bounds!(opt, [-Inf, 0.])
xtol_rel!(opt,1e-4)
min_objective!(opt, myfunc)
inequality_constraint!(opt, (x,g) -> myconstraint(x,g,2,0), 1e-8)
inequality_constraint!(opt, (x,g) -> myconstraint(x,g,-1,1), 1e-8)
(minf,minx,ret) = optimize(opt, [1.234, 5.678])
println("got $minf at $minx after $count iterations (returned $ret)")
这个很好用。它给出了 2 个结果和 11 次迭代
using NLopt
count = 0 # keep track of # function evaluations
function myfunc(x)
x[1]^2 + 5*x[2] - 3
end
function myconstraint(x)
100*x[1] + 2000*x[2] == 100
end
opt = Opt(:LD_MMA, 2)
lower_bounds!(opt, [0, 0])
upper_bounds!(opt,[10,5])
xtol_rel!(opt,1e-10)
min_objective!(opt, myfunc);
inequality_constraint!(opt, (x) -> myconstraint(x), 1e-10)
(minf,minx,ret) = optimize(opt, [0.1,0.1])
这不起作用,它只给出一个结果和 0 次迭代
using NLopt
count = 0 # keep track of # function evaluations
function myfunc(x::Vector, grad::Vector)
x[1]^2 + 5*x[2] - 3
end
function myconstraint(result::Vector, x::Vector, grad::Vector)
100*x[1] + 2000*x[2] == 100
end
opt = Opt(:LD_MMA, 2)
lower_bounds!(opt, [0., 0.])
upper_bounds!(opt, [10.,5.])
xtol_rel!(opt,1e-4)
min_objective!(opt, myfunc)
inequality_constraint!(opt, (x,g) -> myconstraint(x), 1e-8)
(minf,minx,ret) = optimize(opt, [0., 0.])#even with [5.,10.]
这只给了我一个结果和 0 次迭代。
有人知道我做错了什么吗?
我很难根据评论马拉松重建你所做的事情,所以我想我只是提供代码来说明我将如何解决这个问题。请注意,以下代码假定您的不等式约束是 100*x[1] + 2000*x[2] <= 100
:
using NLopt
function myfunc(x::Vector{Float64}, grad::Vector{Float64})
if length(grad) > 0
grad[1] = 2 * x[1]
grad[2] = 5
end
xOut = x[1]^2 + 5*x[2] - 3
println("Obj func = " * string(xOut))
return(xOut)
end
function myconstraint(x::Vector{Float64}, grad::Vector{Float64})
if length(grad) > 0
grad[1] = 100
grad[2] = 2000
end
xOut = 100*x[1] + 2000*x[2] - 100
println("Constraint val = " * string(xOut))
return(xOut)
end
opt = Opt(:LD_MMA, 2)
lower_bounds!(opt, [0, 0])
upper_bounds!(opt,[10,5])
xtol_rel!(opt,1e-10)
min_objective!(opt, myfunc);
inequality_constraint!(opt, myconstraint, 1e-10)
(minf,minx,ret) = optimize(opt, [0.1,0.1])
我的代码和你的代码之间存在三个主要区别:
我已明确包含梯度函数更新。这将使任何 gradient-based 算法(MMA 是其中之一)的收敛例程更有效。
我在每一步打印出我的 objective 函数和约束函数的值。这对于调试目的很有用,并且可以了解幕后发生的事情。
我在我的代码中说得很清楚,我的约束函数的 return 值是 f(x)
,其中约束由方程 [=13] 定义=].这是与 NLopt
.
一起使用的适当语法
您在评论中指出,当您尝试将 inequality_constraint!
更改为 equality_constraint!
时出现错误。这是因为您选择的算法 (MMA) 仅支持不等式约束。 NLopt
算法的描述可以在 here 中找到。注:
only MMA and SLSQP support arbitrary nonlinear inequality constraints, and only SLSQP supports nonlinear equality constraints
因此,将您的算法切换为 :LD_SLSQP
,瞧,您现在可以将不等式约束切换为等式约束。
我正在尝试将 Matlab fmincon 优化函数转换为 julia。 但运气不佳。
我觉得可以用NLopt或者IPopt。 默认示例有效,但当我尝试更改值时,它似乎没有重复。
using NLopt
count = 0 # keep track of # function evaluations
function myfunc(x::Vector, grad::Vector)
if length(grad) > 0
grad[1] = 0
grad[2] = 0.5/sqrt(x[2])
end
global count
count::Int += 1
println("f_$count($x)")
sqrt(x[2])
end
function myconstraint(x::Vector, grad::Vector, a, b)
if length(grad) > 0
grad[1] = 3a * (a*x[1] + b)^2
grad[2] = -1
end
(a*x[1] + b)^3 - x[2]
end
opt = Opt(:LD_MMA, 2)
lower_bounds!(opt, [-Inf, 0.])
xtol_rel!(opt,1e-4)
min_objective!(opt, myfunc)
inequality_constraint!(opt, (x,g) -> myconstraint(x,g,2,0), 1e-8)
inequality_constraint!(opt, (x,g) -> myconstraint(x,g,-1,1), 1e-8)
(minf,minx,ret) = optimize(opt, [1.234, 5.678])
println("got $minf at $minx after $count iterations (returned $ret)")
这个很好用。它给出了 2 个结果和 11 次迭代
using NLopt
count = 0 # keep track of # function evaluations
function myfunc(x)
x[1]^2 + 5*x[2] - 3
end
function myconstraint(x)
100*x[1] + 2000*x[2] == 100
end
opt = Opt(:LD_MMA, 2)
lower_bounds!(opt, [0, 0])
upper_bounds!(opt,[10,5])
xtol_rel!(opt,1e-10)
min_objective!(opt, myfunc);
inequality_constraint!(opt, (x) -> myconstraint(x), 1e-10)
(minf,minx,ret) = optimize(opt, [0.1,0.1])
这不起作用,它只给出一个结果和 0 次迭代
using NLopt
count = 0 # keep track of # function evaluations
function myfunc(x::Vector, grad::Vector)
x[1]^2 + 5*x[2] - 3
end
function myconstraint(result::Vector, x::Vector, grad::Vector)
100*x[1] + 2000*x[2] == 100
end
opt = Opt(:LD_MMA, 2)
lower_bounds!(opt, [0., 0.])
upper_bounds!(opt, [10.,5.])
xtol_rel!(opt,1e-4)
min_objective!(opt, myfunc)
inequality_constraint!(opt, (x,g) -> myconstraint(x), 1e-8)
(minf,minx,ret) = optimize(opt, [0., 0.])#even with [5.,10.]
这只给了我一个结果和 0 次迭代。
有人知道我做错了什么吗?
我很难根据评论马拉松重建你所做的事情,所以我想我只是提供代码来说明我将如何解决这个问题。请注意,以下代码假定您的不等式约束是 100*x[1] + 2000*x[2] <= 100
:
using NLopt
function myfunc(x::Vector{Float64}, grad::Vector{Float64})
if length(grad) > 0
grad[1] = 2 * x[1]
grad[2] = 5
end
xOut = x[1]^2 + 5*x[2] - 3
println("Obj func = " * string(xOut))
return(xOut)
end
function myconstraint(x::Vector{Float64}, grad::Vector{Float64})
if length(grad) > 0
grad[1] = 100
grad[2] = 2000
end
xOut = 100*x[1] + 2000*x[2] - 100
println("Constraint val = " * string(xOut))
return(xOut)
end
opt = Opt(:LD_MMA, 2)
lower_bounds!(opt, [0, 0])
upper_bounds!(opt,[10,5])
xtol_rel!(opt,1e-10)
min_objective!(opt, myfunc);
inequality_constraint!(opt, myconstraint, 1e-10)
(minf,minx,ret) = optimize(opt, [0.1,0.1])
我的代码和你的代码之间存在三个主要区别:
我已明确包含梯度函数更新。这将使任何 gradient-based 算法(MMA 是其中之一)的收敛例程更有效。
我在每一步打印出我的 objective 函数和约束函数的值。这对于调试目的很有用,并且可以了解幕后发生的事情。
我在我的代码中说得很清楚,我的约束函数的 return 值是
f(x)
,其中约束由方程 [=13] 定义=].这是与NLopt
. 一起使用的适当语法
您在评论中指出,当您尝试将 inequality_constraint!
更改为 equality_constraint!
时出现错误。这是因为您选择的算法 (MMA) 仅支持不等式约束。 NLopt
算法的描述可以在 here 中找到。注:
only MMA and SLSQP support arbitrary nonlinear inequality constraints, and only SLSQP supports nonlinear equality constraints
因此,将您的算法切换为 :LD_SLSQP
,瞧,您现在可以将不等式约束切换为等式约束。