Main Content

本页采用了机器翻译。点击此处可查看英文原文。

探索 patternsearch 算法

从 R2022b 开始,patternsearch 有四种算法:

  • "classic"

  • "nups"(非均匀模式搜索)

  • "nups-gps"

  • "nups-mads"

这个例子说明了算法的选择如何影响具有非光滑目标函数的有界问题。

目标函数

此示例的目标函数基于运行示例时可用的 2-D ps_example 函数。

type ps_example
function f = ps_example(x)
%PS_EXAMPLE objective function for patternsearch.

%   Copyright 2003-2021 The MathWorks, Inc.

f = zeros(1,size(x,1));
for i = 1:size(x,1)
    if  x(i,1) < -5
        f(i) = (x(i,1)+5)^2 + abs(x(i,2));
    elseif x(i,1) < -3
        f(i) = -2*sin(x(i,1)) + abs(x(i,2));
    elseif x(i,1) < 0
        f(i) = 0.5*x(i,1) + 2 + abs(x(i,2));
    elseif x(i,1) >= 0
        f(i) = .3*sqrt(x(i,1)) + 5/2 +abs(x(i,2));
    end
end

通过为每两个维度创建距离原点的伪随机偏移,并添加得到的目标,将 ps_example 函数扩展到任意偶数维。请参阅本示例末尾testps 辅助函数的代码。

指定 N = 10 尺寸,并为每个分量设置 -20 到 20 的边界。从点 x0 = [0 0 ... 0] 开始 patternsearch

N = 10;
lb = -20*ones(1,N);
ub = -lb;
x0 = zeros(size(lb));

运行经典算法

设置选项以使用 "classic" 算法并显示目标函数值。

optscl = optimoptions("patternsearch",Algorithm="classic",PlotFcn="psplotbestf");

运行优化。

[xclassic,fvalclassic,eflagclassic,outputclassic] = ...
    patternsearch(@testps,x0,[],[],[],[],lb,ub,[],optscl)
patternsearch stopped because the mesh size was less than options.MeshTolerance.

xclassic = 1×10

   -7.9575    5.9058   -8.5047   -5.5481   -8.9402   -2.8633   -7.5058    0.8919   -5.6967    2.9322

fvalclassic = -10.0000
eflagclassic = 1
outputclassic = struct with fields:
         function: @testps
      problemtype: 'boundconstraints'
       pollmethod: 'gpspositivebasis2n'
    maxconstraint: 0
     searchmethod: []
       iterations: 218
        funccount: 3487
         meshsize: 9.5367e-07
         rngstate: [1x1 struct]
          message: 'patternsearch stopped because the mesh size was less than options.MeshTolerance.'

运行 NUPS 算法

设置选项以使用 "nups" 算法。为了获得可重复的结果,请设置随机种子。

optsnups = optimoptions(optscl,Algorithm="nups");
rng default % For reproducibility
[xnups,fvalnups,eflagnups,outputnups] = ...
    patternsearch(@testps,x0,[],[],[],[],lb,ub,[],optsnups)
patternsearch stopped because the mesh size was less than options.MeshTolerance.

xnups = 1×10

   -7.9575    5.9058   -8.5047   -5.5480   -8.9401   -2.8633   -7.5058    0.8919   -5.6967    2.9322

fvalnups = -9.9999
eflagnups = 1
outputnups = struct with fields:
         function: @testps
      problemtype: 'boundconstraints'
       pollmethod: 'nups'
    maxconstraint: 0
     searchmethod: []
       iterations: 183
        funccount: 1827
         meshsize: 8.5928e-07
         rngstate: [1x1 struct]
          message: 'patternsearch stopped because the mesh size was less than options.MeshTolerance.'

在这种情况下,"nups" 算法使用更少的函数计算,但本质上达到了与 "classic" 算法相同的解。

进一步探索

您还可以尝试 "nups-gps""nups-mads" 算法来查看它们解决这个问题的表现。尽管您无法总是预测哪种算法最适合解决问题,但 "nups" 可以成为一个很好的起始算法,因为它结合了许多自适应特性,使其很可能成为最佳算法。

辅助函数

以下代码会创建 testps 辅助函数。

function y = testps(x) 
    N = numel(x); % Number of variables
    if mod(N,2) == 1
        disp("Number of variables must be even.")
        return
    end
    strm = RandStream("twister",Seed=1); % Set Seed for consistency
    % Use RandStream to avoid affecting the global stream
    dsp = 5*randn(strm,size(x));
    z = x - dsp; % Include random offsets
    y = 0;
    for i = 1:N/2
        y = y + ps_example(z([2*i-1,2*i]));
    end
end

另请参阅

相关主题