模式搜索法(算法分析+python代码解释)

本文详细介绍了模式搜索法的基本原理,包括轴向移动和模式移动的过程,以及算法的步骤和一个实例分析。它强调了算法的简单性、收敛速度及适用范围,适合解决变量较少的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

模式搜索法是1961年由HooksJeeves提出。这种方法的每一步迭代都是交替进行轴向移动和模式移动。轴向移动的目的是探测下降的有利方向,模式移动的目的则是沿着有利方向作加速运动。


目录

基本原理:

算法步骤:

例题分析:

算法代码:

分析


基本原理:

min f(x),x\in R^{n},f:R^{n}\rightarrow R

轴向移动是先从一个点 y 出发,依次沿坐标轴方向 e_{1},e_{2},...,e_{n} 用定步长 \delta_{k} 作探测性的搜索移动,沿 e_{j}(j=1,2,....,n) 作探测性移动按照以下方式进行:

(1)正轴向探测:

        如果 f(y+\delta _{k}e_{j})<f(y) ,探测成功,取 y=y+\delta _{k}e_{j} ;否则,探测失败,再作负轴向探测;

(2)负轴向探测:

        如果 f(y-\delta _{k}e_{j})<f(y) ,探测成功,取 y=y-\delta _{k}e_{j} ;否则,探测失败, y 保持不变;

将每一次探测移动后得到的点,作为下一次探测移动的开始点. 经过 步探测移动,一般可得到使得目标函数值下降得点,这样就完成了一次轴向移动。 每次轴向移动的开始点成为参考点。

设 x_{k+1} 是以点 x_{k} 为参考点进行一次轴向移动所得到的点。

        如果 f(x_{k+1})<f(x_{k}) ,则从点 x_{k+1} 出发作模式移动。

        否则,判断 \delta_{k}< \varepsilon 是否成立。若成立,迭代终止;

                若 \delta_{k}< \varepsilon 不成立且 x_{k+1}=x_{k} ,则缩短步长,以从 x_{k} 出发作轴向移动;

                 \delta_{k}< \varepsilon 不成立且 x_{k+1}\neq x_{k} ,则从 x_{k} 出发作轴向移动。

从点 x_{k+1} 出发的模式移动是值以 1 作为步长沿加速方向 d_{k}=x_{k+1}-x_{k} 移动一步,得到新的参考点。

y=x_{k+1}+d_{k}=2x_{k+1}-x_{k}

然而,从新的参考点 y 出发,仍以 \delta_{k} 为步长进行轴向移动。


算法步骤:

步骤1:选取初始点 x_{0} ,初始步长 \delta_{0} ,给定收缩因子 \alpha \in (0,1),给定允许误差 ε>0,k=0;

步骤2:确定参考点,令 y=x_{k}j=1

步骤3:先从点 y 出发,沿着 e_{j} 作正轴向探测, 如果 f(y+\delta _{k}e_{j})<f(y) ,令 y=y+\delta _{k}e_{j} ,转步骤5;否则,转步骤4;

步骤4:先从点 y 出发,沿着 e_{j} 作负轴向探测,如果 f(y-\delta _{k}e_{j})<f(y) ,令 y=y-\delta _{k}e_{j}

 ,转步骤5;

步骤5:如果 j<n ,令 j=j+1 ,返回步骤3;否则,令 x_{k+1}=y,转步骤6;

步骤6:作模式搜索。如果 f(x_{k+1})<f(x_{k}),令 y=2x_{k+1}-x_{k} ,\delta_{k+1}=\delta_{k},k=k+1,j=1,返回步骤3;否则,转步骤7;

步骤7:如果 \delta_{k}< \varepsilon 停止,得到近似最优解 x_{k} ;否则,转步骤8; 

步骤8:缩短步长,如果 x_{k+1}=x_{k},令 \delta_{k+1}=\alpha \delta_{k},k=k+1,返回步骤2;否则,令x_{k+1}=x_{k} ,\delta_{k+1}= \delta_{k},k=k+1,返回步骤2。


例题分析:

下面我们来用一个简单的例题来解释计算流程:

例题:用坐标轮换法求解 minf(x)=x_{1}^{2}+x_{2}^2-3x_{1}-x_{1}x_{2} ,其中 x_{0}=(0,0)^{T},\delta _{0}=1,\alpha =0.25,\varepsilon =0.1

解:第一次迭代:

y=x_{0}=(0,0)^{T},y+\delta _0e_{1}=(1,2)^{T},f(y)=0

f(y+\delta _0e_{1})=-2<f(y),\therefore y=y+\delta _0e_{1}=(1,0)^{T}

y+\delta _0e_{2}=(1,1)^{T},f(y)=-2,y-\delta _0e_{2}=(1,-1)^{T}

f(y+\delta _0e_{2})=-2=f(y),\therefore f(y-\delta _0e_{2})=0>f(y)

轴向移动结束,x_1=(1,0)^{T}

做模式移动,y=2x_{k+1}-x_{k}=2x_{1}-x_{0}=(2,0)^{T},\delta _{1}=\delta _{0}

第二次迭代:

f(y)=-2,f(y+\delta _1e_{1})=0> f(y),f(y-\delta _1e_{1})=-2= f(y)

f(y+\delta _1e_{2})=-3<f(y)

取 y=y+\delta _1e_{2}=(2,1)^{T}

轴向移动结束,x_2=(2,1)^{T}

f(x_2)<f(x_1) 做模式移动,y=2x_{k+1}-x_{k}=2x_{2}-x_{1}=(3,2)^{T},\delta _{2}=\delta _{1}

第三次迭代:

f(y)=-2,f(y+\delta _1e_{1})=0> f(y),f(y-\delta _1e_{1})=-2= f(y)

f(y+\delta _1e_{2})=0>f(y),f(y-\delta _1e_{2})=-2=f(y)

        轴向移动结束,x_3=(3,2)^{T}

f(x_3)>f(x_2) ,\delta_{2}> \varepsilon,且 x_{3}\neq x_{2} 令 x_{3}=x_{2}=(2,1)^{T}y=x_{3}=(2,1)^{T},\delta _{3}=\delta _{2}

第四次迭代:

f(y)=-3,f(y+\delta _3e_{1})=-2> f(y),f(y-\delta _3e_{1})=-2> f(y)

f(y+\delta _3e_{2})=-2>f(y),f(y-\delta _3e_{2})=-2>f(y)

        轴向移动结束,x_4=(2,1)^{T}

f(x_4)=f(x_3) ,\delta_{3}> \varepsilon,且 x_{4}=x_{3} ,要缩短步长,令 \delta _{4}=\alpha \delta _{3}=0.25y=x_{4}=(2,1)^{T}

第五次迭代:

过程与第四次迭代相似x_{5}=x_{4} 再次缩短步长,令 \delta _{5}=\alpha \delta _{4}=0.0625y=x_{5}=(2,1)^{T}

第六次迭代:

过程与第五次迭代相似x_{6}=x_{5} 再次缩短步长,但此时\delta _{5}=0.0625< 0.1,迭代停止,得到最优解:x_{5}=(2,1)^{T}


算法代码:

'''
模式搜索法
2023.11.19
'''
import numpy as np
from sympy import symbols, diff, solve

x1 = symbols("x1")
x2 = symbols("x2")
f = x1**2 + x2**2 - 3 * x1 - x1 * x2

def run(x1_init, x2_init, ε, δ ,α):
    x_old = [x1_init, x2_init]
    y0 = [x1_init, x2_init]
    while True:
        x_new = Compare(y0,δ)
        x_new = np.array([x_new[0],x_new[1]])
        if f.subs({x1:x_new[0],x2:x_new[1]}) < f.subs({x1:x_old[0],x2:x_old[1]}):
            δ = δ
            y0 = 2 * x_new - x_old
            x_old = x_new
        else:
            if δ <= ε:
                print("算法停止,该精度下的最优解是[%f,%f]" % (x_new[0], x_new[1]))
                break
            else:
                if np.array_equal(x_new, x_old):
                    δ = α * δ
                    y0 = x_old
                else:
                    y0 = x_old
def Compare(x0,δ):
    f0 = f.subs({x1: x0[0], x2: x0[1]})
    e1 = [1, 0]
    e2 = [0, 1]
    y0 = [x0[0] + δ * e1[0], x0[1] + δ * e1[1]]
    f1 = f.subs({x1: y0[0], x2: y0[1]})
    if f1 < f0:
        y = y0
    else:
        y0 = [x0[0] - δ * e1[0], x0[1] - δ * e1[1]]
        f1 = f.subs({x1: y0[0], x2: y0[1]})
        if f1 < f0:
            y = y0
        else:
            y = x0
    f0 = f.subs({x1: y[0], x2: y[1]})
    y0 = [y[0] + δ * e2[0], y[1] + δ * e2[1]]
    f1 = f.subs({x1: y0[0], x2: y0[1]})
    if f1 < f0:
        y = y0
    else:
        y0 = [x0[0] - δ * e2[0], x0[1] - δ * e2[1]]
        f1 = f.subs({x1: y0[0], x2: y0[1]})
        if f1 < f0:
            y = y0
        else:
            y = y
    return y
run(0,0,0.1,1,0.25)

该代码所运算的结果为:

算法停止,该精度下的最优解是[2.000000,1.000000]

分析:

模式搜索法有以下三个特点:

(1)算法简单,程序易于实现;

(2)收敛速度慢;

(3)只适用于变量个数少的问题。

(行文中若有纰漏,希望大家指正)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

背对人潮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值