簡體   English   中英

將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])

我的代碼與您的代碼之間存在三個主要區別:

  1. 我已經明確包含了梯度函數更新。 這將使收斂例程對於任何基於梯度的算法(MMA是其中之一)更加有效。

  2. 我將在每個步驟中打印出目標函數和約束函數的值。 這對於調試目的很有用,並且有助於了解幕后發生的事情。

  3. 我已經在代碼中非常清楚地表明,約束函數的返回值為f(x) ,其中約束由方程f(x) <= 0 這是用於NLopt的適當語法。

您在注釋中表示,嘗試更改inequality_constraint!時出錯inequality_constraint! equality_constraint! 這是因為您選擇的算法(MMA)僅支持不平等約束。 NLopt算法的描述可以在這里找到。 注意:

僅MMA和SLSQP支持任意非線性不等式約束,並且僅SLSQP支持非線性等式約束

因此,將算法切換為:LD_SLSQP ,瞧,現在您可以將不等式約束轉換為等式約束。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM