Julia 精确线搜索算法

Julia 精确线搜索算法,julia,mathematical-optimization,Julia,Mathematical Optimization,我试图在Julia中实现一个简单的线搜索算法。我是朱莉娅编程的新手,所以我正在不断地学习。如果可能的话,我想寻求一些帮助,以更正运行代码时出现的错误 源代码 using LinearAlgebra function bracket_minimum(f, x = 0, s = 1e-2, k = 2.0) a, fa = x, f(x) b, fb = x + s, f(x + s) if(fb > fa) a, b = b, a

我试图在Julia中实现一个简单的线搜索算法。我是朱莉娅编程的新手,所以我正在不断地学习。如果可能的话,我想寻求一些帮助,以更正运行代码时出现的错误

源代码

using LinearAlgebra

function bracket_minimum(f, x = 0, s = 1e-2, k = 2.0)
    a, fa = x, f(x)
    b, fb = x + s, f(x + s)

    if(fb > fa)
        a, b = b, a
        fa, fb = fb, fa
        s = -s
    end

    while(true)
        c, fc = b + s, f(b + s)
        if(fb < fc)
            return a < c ? (a, c) : (c, a)
        else
            a, fa, b, fb = b, fb, c, fc
            s *= k
        end
    end
end

function bisection(f, a₀, b₀, ϵ)

    function D(f,a)
        # Approximate the first derivative using central differences
        h = 0.001
        return (f(a + h) - f(a - h))/(2 * h)
    end

    a = a₀
    b = b₀

    while((b - a) > ϵ)
        c = (a + b)/2.0

        if D(f,c) > 0
            b = c
        else
            a = c
        end
    end

    return (a,b)
end

function line_search(f::Function, x::Vector{Float64}, d::Vector{Float64})
    println("Hello")
    objective = α -> f(x + α*d)
    a, b = bracket_minimum(objective)
    α = bisection(objective, a, b, 1e-5)
    return α, x + α*d
end

f(x) = sin(x[1] * x[2]) + exp(x[2] + x[3]) - x[3]

x = [1,2,3]
d = [0, -1, -1]
α, x_min = line_search(f, x, d)
下面是代码中的一个修复(我已经清理了一些风格方面的东西,但关键问题是,
二分法
返回的是元组而不是值-我已将其更改为返回括号间隔的中心):

最小功能括号(f,x=0.0,s=1e-2,k=2.0)
a、 fa=x,f(x)
b、 fb=x+s,f(x+s)
如果fb>fa
a、 b=b,a
fa,fb=fb,fa
s=-s
结束
虽然是真的
s*=k
c、 fc=b+s,f(b+s)
如果fbϵ
c=(a+b)/2.0
如果D(f,c)>0
b=c
其他的
a=c
结束
结束
返回(a+b)/2#此项已更改
结束
函数行搜索(f::函数,x::向量{Float64},d::向量{Float64})
@断言长度(x)=长度(d)
目标(α)=f(x.+α。*d)
a、 b=括号_最小值(目标值)
α=二等分(目标,a,b,1e-5)
返回α,x.+α。*d
结束
f(x)=sin(x[1]*x[2])+exp(x[2]+x[3])-x[3]
x=[1.0,2.0,3.0]
d=[0.0,-1.0,-1.0]
α、 x_min=行搜索(f,x,d)
我没有对算法进行评论,因为我假设你写这篇文章是作为一个编程练习,你没有试图写最快和最健壮的算法

ERROR: MethodError: no method matching *(::Tuple{Float64,Float64}, ::Array{Int64,1})
Closest candidates are:
  *(::Any, ::Any, ::Any, ::Any...) at operators.jl:538
  *(::Adjoint{var"#s828",var"#s8281"} where var"#s8281"<:(AbstractArray{T,1} where T) where var"#s828"<:Number, ::AbstractArray{var"#s827",1} where var"#s827"<:Number) at C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.5\LinearAlgebra\src\adjtrans.jl:283
  *(::Transpose{T,var"#s828"} where var"#s828"<:(AbstractArray{T,1} where T), ::AbstractArray{T,1}) where T<:Real at C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.5\LinearAlgebra\src\adjtrans.jl:284
function bracket_minimum(f, x = 0.0, s = 1e-2, k = 2.0)
    a, fa = x, f(x)
    b, fb = x + s, f(x + s)

    if fb > fa
        a, b = b, a
        fa, fb = fb, fa
        s = -s
    end

    while true
        s *= k
        c, fc = b + s, f(b + s)
        if fb < fc
            return minmax(a, c)
        else
            a, fa, b, fb = b, fb, c, fc
        end
    end
end

function bisection(f, a₀, b₀, ϵ)

    function D(f, a)
        # Approximate the first derivative using central differences
        h = 0.001
        return (f(a + h) - f(a - h)) / (2 * h)
    end

    a = a₀
    b = b₀

    while (b - a) > ϵ
        c = (a + b) / 2.0

        if D(f, c) > 0
            b = c
        else
            a = c
        end
    end

    return (a + b) / 2 # this was changed
end

function line_search(f::Function, x::Vector{Float64}, d::Vector{Float64})
    @assert length(x) == length(d)
    objective(α) = f(x .+ α .* d)
    a, b = bracket_minimum(objective)
    α = bisection(objective, a, b, 1e-5)
    return α, x .+ α .* d
end

f(x) = sin(x[1] * x[2]) + exp(x[2] + x[3]) - x[3]

x = [1.0, 2.0, 3.0]
d = [0.0, -1.0, -1.0]
α, x_min = line_search(f, x, d)