使用 patternsearch 搜索全局最小值
patternsearch 求解器并不总是收敛到全局最小值。为了增加获得全局最小值的机会,请从随机起点多次重新启动 patternsearch。
多个局部极小值的问题
函数 sawtoothxy 有多个局部极小值,全局最小值为 [0,0],函数值为 0。
function f = sawtoothxy(x,y) [t,r] = cart2pol(x,y); % change to polar coordinates h = cos(2*t - 1/2)/2 + cos(t) + 2; g = (sin(r) - sin(2*r)/2 + sin(3*r)/3 - sin(4*r)/4 + 4) ... .*r.^2./(r+1); f = g.*h; end
为问题创建不对称线性不等式约束,以及远离全局最小值的可行初始点。
A = [1 1
1 -1
-1 1
-1 -1];
b = [200,200,20,10];
fun = @(t)sawtoothxy(t(1),t(2));
rng(10) % Sets random number stream
x0 = [100,-50] + 10*randn(1,2);检查初始点是否可行,并在该点计算函数 sawtoothxy。
A*x0' - b' % Should be negative for a feasible initial point.ans = 4×1
-158.1931
-28.8906
-191.1094
-51.8069
fun(x0)
ans = 1.1681e+03
patternsearch "nups" 算法通常能够高效地找到一个好的解。看看它在求解此问题的表现如何。
options = optimoptions("patternsearch",Algorithm="nups"); [x,fval,eflag,output] = patternsearch(fun,x0,A,b,[],[],[],[],[],options)
patternsearch stopped because the mesh size was less than options.MeshTolerance.
x = 1×2
0.0088 -10.0088
fval = 35.2488
eflag = 1
output = struct with fields:
function: @(t)sawtoothxy(t(1),t(2))
problemtype: 'linearconstraints'
pollmethod: 'nups'
maxconstraint: 0
searchmethod: []
iterations: 61
funccount: 180
meshsize: 6.7893e-07
rngstate: [1×1 struct]
message: 'patternsearch stopped because the mesh size was less than options.MeshTolerance.'
求解器未找到全局最小值。然而,选择不同的起点会得到更好的结果。
x0 = [100,-50] + 10*randn(1,2); % New start point
[x,fval,eflag,output] = patternsearch(fun,x0,A,b,[],[],[],[],[],options)patternsearch stopped because the mesh size was less than options.MeshTolerance.
x = 1×2
10-6 ×
0.0247 -0.3333
fval = 7.1681e-13
eflag = 1
output = struct with fields:
function: @(t)sawtoothxy(t(1),t(2))
problemtype: 'linearconstraints'
pollmethod: 'nups'
maxconstraint: 0
searchmethod: []
iterations: 70
funccount: 161
meshsize: 9.6669e-07
rngstate: [1×1 struct]
message: 'patternsearch stopped because the mesh size was less than options.MeshTolerance.'
这次,求解器达到了全局最小值。但对于不同的问题,您可能需要多次重启求解器。
从随机点重新启动求解器
要搜索全局最小值,请从随机点反复启动 patternsearch。如果问题中所有变量的取值都有明确的边界,你可以使用随机点。
x0 = lb + rand(size(lb)).*(ub - lb);
这些点是在给定边界内均匀随机生成的。
当前问题没有明确的边界条件。然而,线性约束会给出一个可采样的矩形区域。更具实用性的是,你可以推断出变量 和 的上下界。按如下方式选择推断的边界
lb = [-15,-105]; ub = [200,110];
使用均匀采样器反复选择随机点,以尝试获得最佳结果。
N = 20; % Number of attempts to make. rng(600) % Set a point that does not lead to the global minimum. x0 = lb + rand(size(lb)).*(ub - lb); options.Display = "none"; % Suppress output. [x,fval,eflag,output] = patternsearch(fun,x0,A,b,[],[],[],[],[],options); disp(fval) % Starting function value.
35.2488
for i = 2:N x0 = lb + rand(size(lb)).*(ub - lb); [x2,fval2,eflag2,output2] = patternsearch(fun,x0,A,b,[],[],[],[],[],options); if fval2 < fval % Copy results to x, fval, eflag, output x = x2; fval = fval2; eflag = eflag2; output = output2; end end disp(fval)
0
求解器到达全局解。有关搜索全局最小值的其他方法,请参阅 生成起点的方法。