组合优化与凸优化相关算法 Julia实现

news2024/9/27 17:32:24

线性规划

方法有单纯形法(简单,非多项式),椭圆法(复杂,多项式,仅有理论价值),内点法(非多项式,实际效率高)。

以例子说明,目标函数
min ⁡ z = 0 x 1 + 0.1 x 2 + 0.2 x 3 + 0.3 x 4 + 0.8 x 5 \min z = 0 x_1 + 0.1 x_2 + 0.2 x_3 + 0.3 x_4 + 0.8 x_5 minz=0x1+0.1x2+0.2x3+0.3x4+0.8x5
约束条件
s . t . { x 1 + 2 x 2 + x 4 = 100 2 x 3 + 2 x 4 + x 5 = 100 3 x 1 + x 2 + 2 x 3 + 3 x 5 = 100 x 1 , x 2 , x 3 , x 4 , x 5 ≥ 0 s.t. \begin{cases} x_1 + 2 x_2 + x_4 = 100 \\ 2 x_3 + 2 x_4 + x_5 = 100 \\ 3 x_1 + x_2 + 2 x_3 + 3 x_5 = 100 \\ x_1, x_2, x_3, x_4, x_5 ≥ 0 \end{cases} s.t. x1+2x2+x4=1002x3+2x4+x5=1003x1+x2+2x3+3x5=100x1,x2,x3,x4,x50

代码:

using JuMP, GLPK
m = Model(GLPK.Optimizer)
@variable(m, x[1:5] >= 0, integer = true)
@objective(m, Min, 0.1x[2] + 0.2x[3] + 0.3x[4] + 0.8x[5])
@constraint(m, constraint1, x[1] + 2x[2] + x[4] == 100)
@constraint(m, constraint2, 2x[3] + 2x[4] + x[5] == 100)
@constraint(m, constraint3, 3x[1] + x[2] + 2x[3] + 3x[5] == 100)
#print(m)
JuMP.optimize!(m)
#println("Optimal Soutions:")
for i in 1:5
    println("x$i = ", JuMP.value(x[i]))
end
println("z = ", JuMP.objective_value(m))

结果:

x1 = 30.0
x2 = 10.0
x3 = 0.0
x4 = 50.0
x5 = 0.0
z = 16.0

一维搜索

黄金分割和 Fibonacci 法

α < λ < μ < β \alpha < \lambda < \mu < \beta α<λ<μ<β x ∈ [ α , β ] x \in [\alpha, \beta] x[α,β] 上单谷函数 Φ ( x ) \Phi(x) Φ(x),求其最值 x ∗ x^* x,则有:
一,若 Φ ( λ ) ≥ Φ ( μ ) \Phi(\lambda) ≥ \Phi(\mu) Φ(λ)Φ(μ),则 x ∗ ∈ [ λ , β ] x^* \in [\lambda, \beta] x[λ,β]
二,若 Φ ( λ ) < Φ ( μ ) \Phi(\lambda) < \Phi(\mu) Φ(λ)<Φ(μ),则 x ∗ ∈ [ α , μ ] x^* \in [\alpha, \mu] x[α,μ]
如此迭代缩减区间长度,进行精确一维搜索。

对称性推导

通过选择不同的 λ , μ \lambda, \mu λ,μ 有不同策略,而一个好的策略保证对称性 λ − α = β − μ \lambda - \alpha = \beta - \mu λα=βμ,下面推导之。

设归一化区间参数 p = λ − α β − α , q = β − μ β − α p = \frac{\lambda - \alpha}{\beta - \alpha}, q = \frac{\beta - \mu}{\beta - \alpha} p=βαλα,q=βαβμ,则任一个策略即可表示为点对 ( p , q ) (p, q) (p,q),且有 p , q ∈ ( 0 , 1 ) p, q \in (0, 1) p,q(0,1) p + q < 1 p + q < 1 p+q<1,不妨设 x ∗ x^* x [ α , β ] [\alpha, \beta] [α,β] 上均匀分布,则分以下三种情况:
一, x ∗ ∈ [ α , λ ] x^* \in [\alpha, \lambda] x[α,λ],概率为 p p p,此时必然有 Φ ( λ ) < Φ ( μ ) \Phi(\lambda) < \Phi(\mu) Φ(λ)<Φ(μ),下轮区间缩减为 [ α , μ ] [\alpha, \mu] [α,μ]
二, x ∗ ∈ [ μ , β ] x^* \in [\mu, \beta] x[μ,β],概率为 q q q,此时必然有 Φ ( λ ) > Φ ( μ ) \Phi(\lambda) > \Phi(\mu) Φ(λ)>Φ(μ),下轮区间缩减为 [ λ , β ] [\lambda, \beta] [λ,β]
三, x ∗ ∈ [ λ , μ ] x^* \in [\lambda, \mu] x[λ,μ],概率为 1 − p − q 1 - p - q 1pq,此时不妨设 Φ ( λ ) < Φ ( μ ) \Phi(\lambda) < \Phi(\mu) Φ(λ)<Φ(μ) Φ ( λ ) > Φ ( μ ) \Phi(\lambda) > \Phi(\mu) Φ(λ)>Φ(μ) 发生的概率各占一半。

用缩减比 t ( p , q ) t(p, q) t(p,q) 来表示策略的好坏,可由下轮区间长度与本轮区间长度的比值得到。综上,可分为两种情况:
情况一,下轮区间缩减为 [ α , μ ] [\alpha, \mu] [α,μ] 的概率为 1 + p − q 2 \frac{1 + p - q}{2} 21+pq,缩减比为 1 − q 1 - q 1q
情况二,下轮区间缩减为 [ λ , β ] [\lambda, \beta] [λ,β] 的概率为 1 + q − p 2 \frac{1 + q - p}{2} 21+qp,缩减比为 1 − p 1 - p 1p
则有
t ( p , q ) = ( 1 − q ) 1 + p − q 2 + ( 1 − p ) 1 + q − p 2 = 2 − ( p + q ) + ( p − q ) 2 2 t(p, q) = (1 - q) \frac{1 + p - q}{2} + (1 - p) \frac{1 + q - p}{2} = \frac{2 - (p + q) + (p - q)^2}{2} t(p,q)=(1q)21+pq+(1p)21+qp=22(p+q)+(pq)2
而好的策略意味着低的缩减比。

可得在 p + q p+q p+q 一定的条件下,好的策略保证 p = q p = q p=q,即对称性 λ − α = β − μ \lambda - \alpha = \beta - \mu λα=βμ

黄金缩减比推导

经过以上讨论,若只考虑缩减比最优,那 p = q = 1 2 − ϵ p = q = \frac{1}{2} - \epsilon p=q=21ϵ 无疑是最优策略。可实际上,计算 Φ ( λ ) \Phi(\lambda) Φ(λ) Φ ( μ ) \Phi(\mu) Φ(μ) 在大多数情况下都是该算法流程中的主要时间消耗,而区间缩减为 [ α , μ ] [\alpha, \mu] [α,μ] 的情况下 Φ ( λ ) \Phi(\lambda) Φ(λ) 是可以作为下轮计算的已知量的,同理区间缩减为 [ λ , β ] [\lambda, \beta] [λ,β] 的情况下 Φ ( μ ) \Phi(\mu) Φ(μ) 也是可以作为下轮计算的已知量。

换言之,结果区间精度与初始区间精度的比值为 r r r,在最优缩减比 t ∗ = 1 2 + ϵ t^* = \frac{1}{2} + \epsilon t=21+ϵ 下每轮计算两次 Φ ( x ) \Phi(x) Φ(x),时间消耗为 T ( t ∗ ) = 2 log ⁡ t ∗ r T(t^*) = 2 \log_{t^*} r T(t)=2logtr,若存在缩减比 t ′ t' t 下每轮计算一次 Φ ( x ) \Phi(x) Φ(x) 的策略,其时间消耗为 T ( t ′ ) = log ⁡ t ′ r T(t') = \log_{t'} r T(t)=logtr,只需要满足条件 t ′ < t ∗ = 1 2 + ϵ t' < \sqrt{t^*} = \frac{1}{\sqrt{2}} + \epsilon t<t =2 1+ϵ,即 t ′ ≤ 1 2 ≈ 0.707 t' ≤ \frac{1}{\sqrt{2}} \approx 0.707 t2 10.707 即可保证该策略比最优缩减比策略更好。

对于本轮区间参数 ( α , λ , μ , β ) (\alpha, \lambda, \mu, \beta) (α,λ,μ,β) 和下轮区间参数 ( α ′ , λ ′ , μ ′ , β ′ ) (\alpha', \lambda', \mu', \beta') (α,λ,μ,β),保证缩减比
t = μ − α β − α = β − λ β − α = μ ′ − α ′ β ′ − α ′ = β ′ − λ ′ β ′ − α ′ t = \frac{\mu - \alpha}{\beta - \alpha} = \frac{\beta - \lambda}{\beta - \alpha} = \frac{\mu' - \alpha'}{\beta' - \alpha'} = \frac{\beta' - \lambda'}{\beta' - \alpha'} t=βαμα=βαβλ=βαμα=βαβλ
的情况下,希望有如下性质:
α ′ = α , β ′ = μ \alpha' = \alpha, \beta' = \mu α=α,β=μ 时,有 μ ′ = λ \mu' = \lambda μ=λ;( λ ′ = λ \lambda' = \lambda λ=λ 是无法满足的)
α ′ = λ , β ′ = β \alpha' = \lambda, \beta' = \beta α=λ,β=β 时,有 λ ′ = μ \lambda' = \mu λ=μ;( μ ′ = μ \mu' = \mu μ=μ 是无法满足的)
由于左右两种情况对称,故以 α ′ = α , μ ′ = λ , β ′ = μ \alpha' = \alpha, \mu' = \lambda, \beta' = \mu α=α,μ=λ,β=μ 为例,设此时缩减比为 t ϕ t_\phi tϕ,则有
β − λ = μ − α = t ϕ ( β − α ) λ − α = μ ′ − α ′ = t ϕ ( β ′ − α ′ ) = t ϕ ( μ − α ) = t ϕ 2 ( β − α ) \beta - \lambda = \mu - \alpha = t_\phi(\beta - \alpha) \\ \lambda - \alpha = \mu' - \alpha' = t_\phi(\beta' - \alpha') = t_\phi(\mu - \alpha) = t_\phi^2(\beta - \alpha) βλ=μα=tϕ(βα)λα=μα=tϕ(βα)=tϕ(μα)=tϕ2(βα)
得方程
β − α = ( β − λ ) + ( λ − α ) = t ϕ ( β − α ) + t ϕ 2 ( β − α ) \beta - \alpha = (\beta - \lambda) + (\lambda - \alpha) = t_\phi(\beta - \alpha) + t_\phi^2(\beta - \alpha) βα=(βλ)+(λα)=tϕ(βα)+tϕ2(βα)
化简之,即
t ϕ 2 + t ϕ − 1 = 0 t_\phi^2 + t_\phi - 1 = 0 tϕ2+tϕ1=0
t ϕ > 0 t_\phi > 0 tϕ>0 舍去负根,得 t ϕ = 5 − 1 2 ≈ 0.618 t_\phi = \frac{\sqrt{5} - 1}{2} \approx 0.618 tϕ=25 10.618 恰为黄金分割比,满足上文条件为最优策略。此即一维搜索的黄金分割法。

Fibonacci 法

设 Fibonacci 数列 F 0 = 0 , F 1 = 1 , F n = F n − 1 + F n − 2 F_0 = 0, F_1 = 1, F_n = F_{n - 1} + F_{n - 2} F0=0,F1=1,Fn=Fn1+Fn2,由于 lim ⁡ n → ∞ F n F n + 1 = 5 − 1 2 \lim_{n \to \infty} \frac{F_n}{F_{n + 1}} = \frac{\sqrt{5} - 1}{2} limnFn+1Fn=25 1,故可用反向 Fibonacci 数列指导每轮缩减,是为 Fibonacci 法,代码如下:

function FibonacciSection(f, l, u, tol)
    fib = [1, 1]
    while fib[end] * tol < u - l
        push!(fib, fib[end] + fib[end-1])
    end
    m, n = (fib[end-1] * l + fib[end-2] * u) / fib[end], (fib[end-2] * l + fib[end-1] * u) / fib[end]
    for i = length(fib)-1 : -1 : 3
        if f(m) > f(n)
            l, m = m, n
            n = (fib[i-2] * l + fib[i-1] * u) / fib[i]
        else
            u, n = n, m
            m = (fib[i-1] * l + fib[i-2] * u) / fib[i]
        end
    end
    return m
end

二分法

取当前区间 [ α , β ] [\alpha, \beta] [α,β] 中点 λ = α + β 2 \lambda = \frac{\alpha + \beta}{2} λ=2α+β,求导数值 Φ ′ ( λ ) \Phi'(\lambda) Φ(λ),并判断:
Φ ′ ( λ ) > 0 \Phi'(\lambda) > 0 Φ(λ)>0,区间更新为 [ α , λ ] [\alpha, \lambda] [α,λ]
Φ ′ ( λ ) < 0 \Phi'(\lambda) < 0 Φ(λ)<0,区间更新为 [ λ , β ] [\lambda, \beta] [λ,β]
Φ ′ ( λ ) = 0 \Phi'(\lambda) = 0 Φ(λ)=0 λ \lambda λ 为最小点,算法结束。

代码:

function BinarySection(f, grad_f, l, u, tol)
    m = (l + u) / 2
    while u - l > tol
        g = grad_f(m)
        if g > 0.
            u = m
        elseif g < 0.
            l = m
        else
            break
        end
        m = (l + u) / 2
    end
    return m
end

Shubert-Piyavskii 法

若有 ∣ Φ ( λ ) − Φ ( μ ) ∣ ≤ l ∣ λ − μ ∣ , ∀ λ , μ ∈ [ a , b ] \left| \Phi(\lambda) - \Phi(\mu) \right| ≤ l \left| \lambda - \mu \right|, \forall \lambda, \mu \in [a, b] Φ(λ)Φ(μ)lλμ,λ,μ[a,b],则称函数 Φ ( x ) \Phi(x) Φ(x) [ a , b ] [a, b] [a,b] 上是 l l l-Lipschitz 连续的,即导数的幅度存在上界。

Shubert-Piyavskii 法用斜率为 ± l \pm l ±l 的线段,迭代构造 Φ ( x ) \Phi(x) Φ(x) 的锯齿状下界,代码:

function Shubert_Piyavskii(f, L, l, u, tol)
    intersection(p, q) = ((p[1] + q[1]) / 2 + (p[2] - q[2]) / (2 * L), (p[1] - q[1]) * L / 2 + (p[2] + q[2]) / 2)
    m = (l + u) / 2
    Up = [(l, f(l)), (m, f(m)), (u, f(u))]
    Lo = [intersection(Up[1], Up[2]), intersection(Up[2], Up[3])]
    f_min = minimum(map(last, Up))
    while true
        m = argmin(map(last, Lo))
        y = f(Lo[m][1])
        if f_min > y
            f_min = y
            if (f_min - Lo[m][2]) * 2 < L * tol
                break
            end
        end
        Up = vcat(Up[1 : m], [(Lo[m][1], y)], Up[m+1 : end])
        Lo = vcat(Lo[1 : m-1], [intersection(Up[m], Up[m+1]), intersection(Up[m+1], Up[m+2])], Lo[m+1 : end])
    end
    return Lo[m][1]
end

不精确搜索

考虑从 x ( k ) x^{(k)} x(k) 出发,沿方向 d ( k ) d^{(k)} d(k) 寻找新迭代点 x ( k + 1 ) = x ( k ) + s ( k ) = x ( k ) + λ k d ( k ) x^{(k + 1)} = x^{(k)} + s^{(k)} = x^{(k)} + \lambda_k d^{(k)} x(k+1)=x(k)+s(k)=x(k)+λkd(k) 使得 Φ ( x ( k + 1 ) ) \Phi(x^{(k + 1)}) Φ(x(k+1)) 尽可能小。选取步长增大系数 α > 1 \alpha > 1 α>1 和步长缩短系数 β < 1 \beta < 1 β<1 迭代求步长 λ k \lambda_k λk,直到满足给定规则。

代码:

macro LineSearch(cond2)
    quote
        alpha, beta, lambda = 1.5, 0.5, 1.
        while true
            g, s = grad_f(x), lambda * d
            if f(x + s) - f(x) > rho * g' * s
                lambda = beta * lambda
            elseif $cond2
                lambda = alpha * lambda
            else
                break
            end
        end
        return lambda
    end |> esc
end

Goldstein(f, grad_f, x, d, rho)         = @LineSearch(f(x + s) - f(x) < (1. - rho) * g' * s)
Armijo(f, grad_f, x, d, rho, mu)        = @LineSearch(f(x + s) - f(x) < (mu * rho) * g' * s)
Goldstein2(f, grad_f, x, d, rho, sigma) = @LineSearch(f(x + s) - f(x) < sigma * g' * s)
WP(f, grad_f, x, d, rho, sigma)         = @LineSearch(grad_f(x + s)' * s < sigma * g' * s)
WP2(f, grad_f, x, d, rho, eta)          = @LineSearch(abs(grad_f(x + s)' * d) > -eta * g' * d)
Goldstein 规则

(1) Φ ( x ( k + 1 ) ) − Φ ( x ( k ) ) ≤ ρ ∇ Φ T ( x ( k ) ) s ( k ) \Phi(x^{(k + 1)}) - \Phi(x^{(k)}) ≤ \rho \nabla \Phi^T(x^{(k)}) s^{(k)} Φ(x(k+1))Φ(x(k))ρΦT(x(k))s(k)
(2) Φ ( x ( k + 1 ) ) − Φ ( x ( k ) ) ≥ ( 1 − ρ ) ∇ Φ T ( x ( k ) ) s ( k ) \Phi(x^{(k + 1)}) - \Phi(x^{(k)}) ≥ (1 - \rho) \nabla \Phi^T(x^{(k)}) s^{(k)} Φ(x(k+1))Φ(x(k))(1ρ)ΦT(x(k))s(k)
其中 ρ ∈ ( 0 , 1 2 ) \rho \in (0, \frac{1}{2}) ρ(0,21),实际取 0.1 或更小。

Armijo 规则

(1) 同 Goldstein(1)
(2) Φ ( x ( k + 1 ) ) − Φ ( x ( k ) ) ≥ μ ∇ Φ T ( x ( k ) ) s ( k ) \Phi(x^{(k + 1)}) - \Phi(x^{(k)}) ≥ \mu \nabla \Phi^T(x^{(k)}) s^{(k)} Φ(x(k+1))Φ(x(k))μΦT(x(k))s(k)
其中 μ ∈ ( 5 , 10 ) \mu \in (5, 10) μ(5,10)

Goldstein 改进规则

(1) 同 Goldstein(1)
(2) Φ ( x ( k + 1 ) ) − Φ ( x ( k ) ) ≥ σ ∇ Φ T ( x ( k ) ) s ( k ) \Phi(x^{(k + 1)}) - \Phi(x^{(k)}) ≥ \sigma \nabla \Phi^T(x^{(k)}) s^{(k)} Φ(x(k+1))Φ(x(k))σΦT(x(k))s(k)
其中 σ ∈ ( ρ , 1 ) \sigma \in (\rho, 1) σ(ρ,1)

Wolfe-Powell 规则

(1) 同 Goldstein(1)
(2) ∇ Φ T ( x ( k + 1 ) ) s ( k ) ≥ σ ∇ Φ T ( x ( k ) ) s ( k ) \nabla \Phi^T(x^{(k + 1)}) s^{(k)} ≥ \sigma \nabla \Phi^T(x^{(k)}) s^{(k)} ΦT(x(k+1))s(k)σΦT(x(k))s(k)
其中 σ ∈ ( ρ , 1 ) \sigma \in (\rho, 1) σ(ρ,1)

Wolfe-Powell 改进规则

(1) 同 Goldstein(1)
(2) ∣ ∇ Φ T ( x ( k + 1 ) ) d ( k ) ∣ ≤ − η ∇ Φ T ( x ( k ) ) d ( k ) \left| \nabla \Phi^T(x^{(k + 1)}) d^{(k)} \right| ≤ - \eta \nabla \Phi^T(x^{(k)}) d^{(k)} ΦT(x(k+1))d(k) ηΦT(x(k))d(k)
其中 η ∈ ( 0 , 1 ) \eta \in (0, 1) η(0,1),当 η = 0 \eta = 0 η=0 即为精确一维搜索,当 η = 0.1 \eta = 0.1 η=0.1 可看作近似的精确一维搜索。

无约束最优化

无约束最优化问题 min ⁡ f ( x ) , f : R n → R \min f(x), f: \mathbb{R}^n \to \mathbb{R} minf(x),f:RnR 往往采用迭代下降的方法求解,即 x ( k + 1 ) = x ( k ) + λ k d ( k ) x^{(k + 1)} = x^{(k)} + \lambda_k d^{(k)} x(k+1)=x(k)+λkd(k),不同算法间的区别在于求得 d ( k ) d^{(k)} d(k) 的方式和得出的值不同。

f ( x ) f(x) f(x) 为二次函数时,写成二次型 f ( x ) = 1 2 x T A x + b T x + c , ∇ f ( x ) = A x + b f(x) = \frac{1}{2} x^T A x + b^T x + c, \nabla f(x) = Ax + b f(x)=21xTAx+bTx+c,f(x)=Ax+b 带入方程
∇ f T ( x + λ d ) d = 0 \nabla f^T(x + \lambda d) d = 0 fT(x+λd)d=0

( A ( x + λ d ) + b ) T d = 0 (A(x + \lambda d) + b)^T d = 0 (A(x+λd)+b)Td=0
化简得最佳步长 λ \lambda λ
λ = − d T ( A x + b ) d T A d \lambda = -\frac{d^T (Ax + b)}{d^T A d} λ=dTAddT(Ax+b)
f ( x ) f(x) f(x) 非二次函数,则需要线搜索得到最佳步长。

有约束最优化问题可通过罚因子方法或增广 Lagrange 方法转化为无约束最优化问题求解。

测试选用 Rosenbrock Banana 函数
f ( x ) = ( a − x 1 ) 2 + b ( x 2 − x 1 2 ) 2 f(x) = (a - x_1)^2 + b (x_2 - x_1^2)^2 f(x)=(ax1)2+b(x2x12)2
其有全局极小点 ( a , a 2 ) (a, a^2) (a,a2),取 a = 1 , b = 5 a = 1, b = 5 a=1,b=5,初始解 x 0 = ( 1 , − 1 ) T x_0 = (1, -1)^T x0=(1,1)T。代码:

using LinearAlgebra, Optim
using Plots

macro iterDescent(part0, part1, part2)
    quote
        x, r = x0, [x0]
        $part0
        for i = 1 : max_iter
            $part1
            if norm(d) < tol
                break
            end
            a = Optim.minimizer(optimize(a -> f.f(x + a * d), -1., 1.))
            s = a * d
            if norm(s) < tol
                break
            end
            x = x + s
            $part2
            push!(r, x)
        end
        return r
    end |> esc
end

function draw(p)
    for i = 2 : length(p)
        plot!([p[i - 1][1], p[i][1]], [p[i - 1][2], p[i][2]], color = :black, legend = false, w = 1)
    end
end

function RosenbrockBanana(a, b)
    (
        f = x::Vector{Float64} -> (a - x[1])^2 + b * (x[2] - x[1]^2)^2,
        g = x::Vector{Float64} -> [-2 * (a - x[1]) - 4 * b * x[1] * (x[2] - x[1]^2); 2 * b * (x[2] - x[1]^2)],
        h = x::Vector{Float64} -> [(2 - 4 * b * (x[2] - 3 * x[1]^2)) (-4 * b * x[1]); (-4 * b * x[1]) (2 * b)]
    )
end

rb = RosenbrockBanana(1, 5)
contour(range(-2, 2, length = 1000), range(-2, 2, length = 1000), (x, y) -> rb.f([x, y]),
    aspect_ratio = 1, levels = 100, color=:turbo, xlims = (-2, 2), ylims = (-2, 2))
x0 = [1., -1.]

坐标轮换法

迭代方向为坐标轴,即单位基向量,每 n n n 轮一循环。

代码:

CyclicCoordinate(f, x0, tol = 1e-6, max_iter = 1000) = @iterDescent(
    n = length(x0),
    begin
        d = zeros(n); d[(i - 1) % n + 1] = 1
    end,
    nothing
)
draw(CyclicCoordinate(rb, x0))

结果:
Fig. 1

Hooke-Jeeves 法

在坐标轮换法基础上加上第 n + 1 n + 1 n+1 轮的加速步,方向为 d ( k ) = x ( k ) − x ( k − n − 1 ) d^{(k)} = x^{(k)} - x^{(k - n - 1)} d(k)=x(k)x(kn1),每 n + 1 n + 1 n+1 轮一循环。

代码:

HookeJeeves(f, x0, tol = 1e-6, max_iter = 1000) = @iterDescent(
    begin
        n = length(x0); l = zeros(n)
    end,
    begin
        if i % (n + 1) > 0
            d = zeros(n); d[i % (n + 1)] = 1
        else
            d = l
        end
    end,
    begin
        if i % (n + 1) > 0
            l[i % (n + 1)] += a
        else
            l = s
        end
    end
)
draw(HookeJeeves(rb, x0))

结果:
Fig. 2

Rosenbrock 法

1 1 1 n n n 轮同坐标轮换法,然后将前 n n n 轮的位移 d ( k ) = x ( k ) − x ( k − n ) d^{(k)} = x^{(k)} - x^{(k - n)} d(k)=x(k)x(kn) 作为第 n + 1 n + 1 n+1 轮的方向,并进行 Gram-Schmidt 正交化形成新的基,每 n n n 轮一循环。
a j = { d j , λ j = 0 Σ i = j n λ i d i , λ j ≠ 0 , b j = { a j , j = 1 a j − Σ i = 1 j − 1 ( a j T d ‾ i ) d ‾ i , j ≥ 2 , d ‾ j = b j ∥ b j ∥ a_j = \begin{cases} d_j, & \lambda_j = 0 \\ \Sigma_{i = j}^n \lambda_i d_i, & \lambda_j ≠ 0 \end{cases}, b_j = \begin{cases} a_j, & j = 1 \\ a_j - \Sigma_{i = 1}^{j - 1} (a_j^T \overline{d}_i) \overline{d}_i, & j ≥ 2 \end{cases}, \overline{d}_j = \frac{b_j}{\Vert b_j \Vert} aj={dj,Σi=jnλidi,λj=0λj=0,bj={aj,ajΣi=1j1(ajTdi)di,j=1j2,dj=bjbj

代码:

Rosenbrock(f, x0, tol = 1e-6, max_iter = 1000) = @iterDescent(
    begin
        n = length(x0); l = zeros(n)
        b = []
        for i = 1 : n
            push!(b, zeros(n))
            b[end][i] = 1
        end
    end,
    d = b[(i - 1) % n + 1],
    begin
        l[(i - 1) % n + 1] = a
        if i % n == 0
            t = zeros(n)
            for j = n : -1 : 1
                if l[j] != 0
                    t += l[j] * b[j]
                    b[j] = t
                end
            end
            for j = 1 : n
                t = zeros(n)
                for k = 1 : j - 1
                    t += (b[j]' * b[k]) * b[k]
                end
                b[j] -= t
                b[j] /= norm(b[j])
            end
            l = zeros(n)
        end
    end
)
draw(Rosenbrock(rb, x0))

结果:
Fig. 3

梯度下降法

迭代方向为梯度下降方向。(二维和坐标轮换法类似,更高维情况有不同)

代码:

GradientDescent(f, x0, tol = 1e-6, max_iter = 1000) = @iterDescent nothing d = -f.g(x) nothing
draw(GradientDescent(rb, x0))

结果:
Fig. 4

Newton 法

代码:

Newton(f, x0, tol = 1e-6, max_iter = 1000) = @iterDescent nothing d = -f.h(x) \ f.g(x) nothing
draw(Newton(rb, x0))

结果:
Fig. 5

DFP 法

H k + 1 = H k − H k y k ( H k y k ) T ( y k ) T H k y k + s k ( s k ) T ( y k ) T s k H^{k+1} = H^k - \frac{H^k y^k (H^k y^k)^T}{(y^k)^T H^k y^k} + \frac{s^k (s^k)^T}{(y^k)^T s^k} Hk+1=Hk(yk)THkykHkyk(Hkyk)T+(yk)Tsksk(sk)T

代码:

DFP(f, x0, tol = 1e-6, max_iter = 1000) = @iterDescent(
    begin
        g, H = f.g(x0), Matrix{Float64}(I, length(x0), length(x0))
    end,
    d = -H * g,
    begin
        g_new = f.g(x)
        y, g = g_new - g, g_new
        H = H - ((H * y) * (H * y)') / (y' * H * y) + (s * s') / (y' * s)
    end
)
draw(DFP(rb, x0))

结果:
Fig. 6

BFGS 法

H k + 1 = ( I − ρ k y k ( s k ) T ) T H k ( I − ρ k y k ( s k ) T ) + ρ k s k ( s k ) T H^{k+1} = (I - \rho_k y^k (s^k)^T)^T H^k (I - \rho_k y^k (s^k)^T) + \rho_k s^k (s^k)^T Hk+1=(Iρkyk(sk)T)THk(Iρkyk(sk)T)+ρksk(sk)T
其中 ρ k = 1 ( s k ) T y k \rho_k = \frac{1}{(s^k)^T y^k} ρk=(sk)Tyk1

代码:

BFGS(f, x0, tol = 1e-6, max_iter = 1000) = @iterDescent(
    begin
        g, H, E = f.g(x0), Matrix{Float64}(I, length(x0), length(x0)), Matrix{Float64}(I, length(x0), length(x0))
    end,
    d = -H * g,
    begin
        g_new = f.g(x)
        y, g = g_new - g, g_new
        rho = 1 / (s' * y)
        H = (E - rho * y * s')' * H * (E - rho * y * s') + rho * s * s'
    end
)
draw(BFGS(rb, x0))

结果:
Fig. 7

Fletcher-Reeves 共轭梯度法

代码:

ConjugateGradientFR(f, x0, tol = 1e-6, max_iter = 1000) = @iterDescent(
    begin
        g = f.g(x0); d = -g
    end,
    nothing,
    begin
        g_new = f.g(x)
        b, g = (g_new' * g_new) / (g' * g), g_new
        d = - g_new + b * d
    end
)
draw(ConjugateGradientFR(rb, x0))

结果:
Fig. 8

References

北大李东风 Julia语言入门 教材:https://www.math.pku.edu.cn/teachers/lidf/docs/Julia/html/_book/index.html
快速入门: 一份简单而粗略的语言概览 :https://cheatsheet.juliadocs.org/zh-cn/
最优化:建模、算法与理论 (刘浩洋等)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1975427.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++第五篇 类和对象(下) 初始化列表

目录 1.再探构造函数 2.类型转换 3.static成员 4.友元 friiend 1.再探构造函数 (1).之前我们实现构造函数时&#xff0c;初始化成员变量主要使用函数体内赋值&#xff0c;构造函数初始化还有一种方式&#xff0c;就是初始化列表&#xff0c;初始化列表的使用方式是以一个冒…

[Spring] SpringBoot统一功能处理与图书管理系统

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…

分销商城小程序系统如何开发

uni-app框架&#xff1a;使用Vue.js开发跨平台应用的前端框架&#xff0c;编写一套代码&#xff0c;可编译到Android、小程序等平台。 框架支持:springboot/Ssm/thinkphp/django/flask/express均支持 前端开发:vue.js 可选语言&#xff1a;pythonjavanode.jsphp均支…

EDI是什么:EDI系统功能介绍

EDI全称Electronic Data Interchange&#xff0c;也被称为“无纸化贸易”。EDI实现企业间&#xff08;B2B&#xff09;自动化通信&#xff0c;帮助贸易伙伴和组织完成更多的工作、加快物流时间并消除人为错误。 EDI遵从国际报文标准&#xff0c;使得业务数据按照结构化或是标准…

音频文件怎么转换成mp3?这5种方法快速转换

音频文件格式繁多&#xff0c;从WAV到FLAC&#xff0c;从AAC到OGG&#xff0c;每一种都有其独特的优势和应用场景。但当我们需要将音频文件分享给朋友、上传到网络平台或进行跨设备播放时&#xff0c;MP3格式因其广泛的兼容性和较小的文件体积&#xff0c;往往成为首选。给大家…

「字符串」实现Trie(字典树|前缀树)的功能 / 手撕数据结构(C++)

概述 在浏览器搜索栏里输入几个字&#xff0c;就弹出了以你的输入为开头的一系列句子。浏览器是怎么知道你接下来要输什么的&#xff1f; 来看看字典树干了什么。 字典树是一种高效记录字符串和查找字符串的数据结构。它以每个字符作为一个节点对字符串进行分割记录&#xff0c…

48 集合应用案例

编写代码时除了要准确地实现功能之外&#xff0c;还要考虑代码的优化&#xff0c;尽量找到一种更快、更好的方法实现预定功能。Python 字典和集合都使用哈希表来存储元素&#xff0c;元素查找速度非常快&#xff0c;关键字 in 作用于字典和集合时比作用于列表要快得多。 impor…

【数据结构之单链表的实现(不带头)】

1.单链表 1.1概念与结构 链表是一种物理存储结构上非连续&#xff0c;非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针连接次序实现的。 可以用下图便于理解 节&#xff08;结&#xff09;点&#xff1a; 与顺序表不同的是&#xff0c;链表里面的每节“车…

三十种未授权访问漏洞合集

未授权访问漏洞介绍 未授权访问可以理解为需要安全配置或权限认证的地址、授权页面存在缺陷&#xff0c;导致其他用户可以直接访问&#xff0c;从而引发重要权限可被操作、数据库、网站目录等敏感信息泄露。---->目录遍历 目前主要存在未授权访问漏洞的有:NFS服务&a…

百度飞桨 OCR识别

百度飞桨 OCR识别代码 import warnings import time import cv2 as cv import paddlehub as hub # Load the image img cv.imread("1.jpg") height, width, channels img.shape imglist [img] ocr hub.Module(name"ch_pp-ocrv3", enable_mkldnnTrue) …

从Axure入门,开始了解产品

​不少想要求职产品经理的小伙伴在问一个问题&#xff1a;我是一个纯小白&#xff0c;一点基础都没有&#xff0c;我该如何入门产品呢&#xff1f;当然想要入门产品&#xff0c;很多人都有自己的一套方法&#xff0c;这里推荐其中的一种方法&#xff0c;从原型工具&#xff0c;…

ModuleNotFoundError: No Module Named openai

题意&#xff1a;Python 无法在环境中找到名为 openai 的模块 问题背景&#xff1a; import requests from bs4 import BeautifulSoup import openai #write each line of nuclear.txt to a list with open(nuclear.txt, r) as f:lines f.readlines()#remove the newline cha…

Spring源码-ClassPathXmlApplicationContext的refresh()都做了什么?

AbstractApplicationContext的refresh方法 /*** 用给定的父类创建一个新的ClassPathXmlApplicationContext* Create a new ClassPathXmlApplicationContext with the given parent,* 从给定的XML文件加载定义* loading the definitions from the given XML files.* param confi…

UE5 从零开始制作跟随的大鹅

文章目录 二、绑定骨骼三、创建 ControlRig四、创建动画五、创建动画蓝图六、自动寻路七、生成 goose八、碰撞 和 Physics Asset缺点 # 一、下载模型 首先我们需要下载一个静态网格体&#xff0c;这里我们可以从 Sketchfab 中下载&#xff1a;Goose Low Poly - Download Free …

十条线路:畅享张北草原天路玩法

2024年6月6日&#xff0c;张家口市政府新闻办召开新闻发布会&#xff0c;发布10条草原天路精品旅游线路&#xff0c;同时就草原天路今年改造提升重点工作进行介绍。其中&#xff0c;10条精品旅游线路包含5条玩转天路经典线路和5条穿越天路新玩法线路。 1、寻“天路之巅”网红打…

Java并发编程 使用锁和状态位来控制线程的执行顺序

Java线程生命周期的认识 对于线程的生命周期&#xff0c;在Java和操作系统中&#xff0c;在概念上有一点小小的不同。 在操作系统层面上&#xff0c;线程的生命周期如下&#xff1a; 1.新建 2.就绪 3.阻塞 4.运行 5.终止 而在Java层面上&#xff0c;则把线程的阻塞状态又划分…

详细分析Flask部署云服务器(图文介绍)

目录 前言1. 安装配置2. 代码部署3. 服务配置4. 自启动前言 Nginx信息补充阅读: Nginx从入门到精通(全)Nginx配置静态网页访问(图文界面)本文着重提供思路逻辑 1. 安装配置 最好的方式是安装docker,通过docker安装nginx,推荐阅读:Docker零基础从入门到精通(全)包环…

与用户有关的接口

1.获取用户详细信息 跟着黑马程序员继续学习SpringBoot3Vue3 用户登录成功之后跳转到首页&#xff0c;需要获取用户的详细信息 打开接口文档 使用Token令牌解析得到用户名 我们需要根据用户名查询用户&#xff0c;获取详细信息 但是请求参数是无&#xff0c;由于都需要携…

标题生成器:开启创意写作的新篇章

文章目录 角色与目标标题生成器的功能标题生成器的优势指导原则限制与澄清应用场景对创意写作的影响智能体发布到微信公众号配置公众号菜单配置自动回复自动回复文本链接自动回复二维码图片 标题生成器的未来发展总结 博主介绍&#xff1a;全网粉丝10w、CSDN合伙人、华为云特邀…

C++入门基本语法(1)

一、命名空间namespace 定义变量、函数时&#xff0c;定义的名称可能会和头文件中或者自己重复使用的名称冲突&#xff1b;namespace可以对标识符的名称进行本地化&#xff0c;以避免冲突的问题&#xff1b; ## 例如&#xff1a; ## 出现这种问题的原因&#xff1a; &#x…