模式搜索法是1961年由Hooks和Jeeves提出。这种方法的每一步迭代都是交替进行轴向移动和模式移动。轴向移动的目的是探测下降的有利方向,模式移动的目的则是沿着有利方向作加速运动。
目录
分析:
基本原理:
轴向移动是先从一个点 y 出发,依次沿坐标轴方向 用定步长
作探测性的搜索移动,沿
作探测性移动按照以下方式进行:
(1)正轴向探测:
如果 ,探测成功,取
;否则,探测失败,再作负轴向探测;
(2)负轴向探测:
如果 ,探测成功,取
;否则,探测失败, y 保持不变;
将每一次探测移动后得到的点,作为下一次探测移动的开始点. 经过 n 步探测移动,一般可得到使得目标函数值下降得点,这样就完成了一次轴向移动。 每次轴向移动的开始点成为参考点。
设 是以点
为参考点进行一次轴向移动所得到的点。
如果 ,则从点
出发作模式移动。
否则,判断 是否成立。若成立,迭代终止;
若 不成立且
,则缩短步长,以从
出发作轴向移动;
若 不成立且
,则从
出发作轴向移动。
从点 出发的模式移动是值以 1 作为步长沿加速方向
移动一步,得到新的参考点。
然而,从新的参考点 y 出发,仍以 为步长进行轴向移动。
算法步骤:
步骤1:选取初始点 ,初始步长
,给定收缩因子
,给定允许误差 ε>0,k=0;
步骤2:确定参考点,令 ,
步骤3:先从点 y 出发,沿着 作正轴向探测, 如果
,令
,转步骤5;否则,转步骤4;
步骤4:先从点 y 出发,沿着 作负轴向探测,如果
,令
,转步骤5;
步骤5:如果 ,令
,返回步骤3;否则,令
,转步骤6;
步骤6:作模式搜索。如果 ,令
,
,返回步骤3;否则,转步骤7;
步骤7:如果 停止,得到近似最优解
;否则,转步骤8;
步骤8:缩短步长,如果 ,令
,返回步骤2;否则,令
,
,返回步骤2。
例题分析:
下面我们来用一个简单的例题来解释计算流程:
例题:用坐标轮换法求解 ,其中
。
解:第一次迭代:
轴向移动结束,
做模式移动,;
第二次迭代:
取
轴向移动结束,
又 做模式移动,
;
第三次迭代:
轴向移动结束,
又 ,
,且
令
,
;
第四次迭代:
轴向移动结束,
又 ,
,且
,要缩短步长,令
,
;
第五次迭代:
过程与第四次迭代相似 再次缩短步长,令
,
;
第六次迭代:
过程与第五次迭代相似 再次缩短步长,但此时
,迭代停止,得到最优解:
算法代码:
'''
模式搜索法
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)只适用于变量个数少的问题。
(行文中若有纰漏,希望大家指正)