主要内容

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

细化起点

关于优化起点

如果问题的某些分量无约束,GlobalSearchMultiStart 将使用人工边界在每个分量中均匀地生成随机起点。但是,如果您的问题具有遥远的极小值,则需要广泛分散的起点来找到这些极小值。

使用这些方法可以获得广泛分散的起点:

  • 在您的 problem 结构体中给出广泛分离的边界。

  • RandomStartPointSet 对象与 MultiStart 算法一起使用。在 RandomStartPointSet 对象中设置 ArtificialBound 属性的一个较大值。

  • CustomStartPointSet 对象与 MultiStart 算法一起使用。使用广泛分散的起点。

每种方法都有优点和缺点。

方法优点缺点
problem 中给出边界自动生成点制作更复杂的 Hessian
可与 GlobalSearch 结合使用不清楚该把边界设多大
容易做到变化 problem
边界可能不对称 仅限均匀点
RandomStartPointSet 中的大 ArtificialBound自动生成点仅限 MultiStart
不改变 problem仅限对称、均匀的点
容易做到不清楚 ArtificialBound 应该设置多大
CustomStartPointSet可自定义仅限 MultiStart
不改变 problem需要编程来生成点

生成起点的方法

均匀网格

要生成均匀的起点网格:

  1. 使用 ndgrid 生成多维数组。给出每个分量的下界、间距和上界。

    例如,要生成一组三维数组

    • 第一个分量从 -2 到 0,间距为 0.5

    • 第二个分量从 0 到 2,间距 0.25

    • 第三个分量从 -10 到 5,间距 1

    [X,Y,Z] = ndgrid(-2:.5:0,0:.25:2,-10:5);
  2. 将数组放入单个矩阵中,每行代表一个起点。例如:

    W = [X(:),Y(:),Z(:)];

    在这个例子中,W 是一个 720×3 的矩阵。

  3. 将矩阵放入 CustomStartPointSet 对象中。例如:

    custpts = CustomStartPointSet(W);

CustomStartPointSet 对象作为第三个输入来调用 run。例如,

% Assume problem structure and ms MultiStart object exist
[x,fval,flag,outpt,manymins] = run(ms,problem,custpts);

扰动网格

与稍微受干扰的起点相比,整数起点可能产生不太稳健的解。

要获得一组扰动的起点:

  1. 按照 均匀网格 的步骤 1-2 生成起点矩阵。

  2. 通过添加均值为 0 且方差相对较小的随机正态矩阵来扰乱起点。

    对于 均匀网格 中的例子,在制作 W 矩阵后,添加一个扰动:

    [X,Y,Z] = ndgrid(-2:.5:0,0:.25:2,-10:5);
    W = [X(:),Y(:),Z(:)];
    W = W + 0.01*randn(size(W));
  3. 将矩阵放入 CustomStartPointSet 对象中。例如:

    custpts = CustomStartPointSet(W);

CustomStartPointSet 对象作为第三个输入来调用 run。例如,

% Assume problem structure and ms MultiStart object exist
[x,fval,flag,outpt,manymins] = run(ms,problem,custpts);

不受约束的组件的点分布广泛

问题的某些分量可能缺少下界。例如:

  • 尽管没有明确的边界,但还是存在着分量无法达到的水平。例如,如果一个分量代表一颗钻石的重量,则隐含的上界是 1 公斤(希望钻石的重量低于 10 克)。在这种情况下,给出隐式边界作为上界。

  • 确实没有上界。例如,计算机文件的大小(以字节为单位)没有有效的上界。如今最大的规模可以是千兆字节或兆兆字节,但 10 年后,谁知道呢?

对于真正无界分量,可以使用以下采样方法。要在每个区域 (exp(n),exp(n+1)) 中生成大约 1/n 个点,请使用以下公式。如果 u 是随机的并且从 0 到 1 均匀分布,那么 r = 2u – 1 就是在 -1 和 1 之间均匀分布。取

y=sgn(r)(exp(1/|r|)e).

y 是对称且随机的。对于由 lb 限定的变量,取

y=lb+(exp(1/u)e).

类似地,对于 ub 上方有界的变量,取

y=ub(exp(1/u)e).

例如,假设您有一个三维问题

  • x(1) > 0

  • x(2) < 100

  • x(3) 无约束

为了使 150 个起点满足以下约束:

u = rand(150,3);
r1 = 1./u(:,1);
r1 = exp(r1) - exp(1);
r2 = 1./u(:,2);
r2 = -exp(r2) + exp(1) + 100;
r3 = 1./(2*u(:,3)-1);
r3 = sign(r3).*(exp(abs(r3)) - exp(1));
custpts = CustomStartPointSet([r1,r2,r3]);

以下是该算法的变体。通过下界方法生成一个介于 0 和无穷大之间的数字。使用该数字作为点的半径。通过对每个分量取随机数并乘以半径来生成该点的其他分量。您可以在乘以半径之前对随机数进行标准化,因此它们的范数为 1。有关此方法的实际示例,请参阅 没有边界且起点分布广泛的 MultiStart

示例:寻找更好的解

MultiStart 无法在 寻找全局或多个局部最小值 中找到全局最小值。有两种简单的方法可以寻找更好的解:

  • 使用更多起点

  • 给搜索空间设定更严格的边界

设置问题结构体和 MultiStart 对象:

problem = createOptimProblem('fminunc',...
    'objective',@(x)sawtoothxy(x(1),x(2)),...
    'x0',[100,-50],'options',...
    optimoptions(@fminunc,'Algorithm','quasi-newton'));
ms = MultiStart;

使用更多起点

对问题运行 MultiStart,得到 200 个起点,而不是 50 个:

rng(14,'twister') % for reproducibility
[x,fval,exitflag,output,manymins] = run(ms,problem,200)
MultiStart completed some of the runs from the start points.

53 out of 200 local solver runs converged with a positive local solver exit flag.

x =

   1.0e-06 *

   -0.2284   -0.5567


fval =

   2.1382e-12


exitflag =

     2


output = 

  struct with fields:

                funcCount: 32670
         localSolverTotal: 200
       localSolverSuccess: 53
    localSolverIncomplete: 147
    localSolverNoSolution: 0
                  message: 'MultiStart completed some of the runs from the start points.↵↵53 out of 200 local solver runs converged with a positive local solver exit flag.'

manymins = 
  1x53 GlobalOptimSolution

  Properties:
    X
    Fval
    Exitflag
    Output
    X0

这次 MultiStart 找到了全局最小值,并找到了 51 个局部极小值。

要查看局部解的范围,请输入 histogram([manymins.Fval],10)

更加严格的起点约束

假设您认为有趣的局部解的所有分量的绝对值都小于 100。起点边界的默认值为 1000。要使用不同的边界值,请生成一个 RandomStartPointSet,并将 ArtificialBound 属性设置为 100

startpts = RandomStartPointSet('ArtificialBound',100,...
    'NumStartPoints',50);
[x,fval,exitflag,output,manymins] = run(ms,problem,startpts)
MultiStart completed some of the runs from the start points.

29 out of 50 local solver runs converged with a positive local solver exit flag.

x =

   1.0e-08 *

    0.9725   -0.6198


fval =

   1.4955e-15


exitflag =

     2


output = 

  struct with fields:

                funcCount: 7431
         localSolverTotal: 50
       localSolverSuccess: 29
    localSolverIncomplete: 21
    localSolverNoSolution: 0
                  message: 'MultiStart completed some of the runs from the start points.↵↵29 out of 50 local solver runs converged with a positive local solver exit flag.'

manymins = 
  1x25 GlobalOptimSolution

  Properties:
    X
    Fval
    Exitflag
    Output
    X0

MultiStart 找到了全局最小值,并找到了 22 个不同的局部解。要查看局部解的范围,请输入 histogram([manymins.Fval],10)

与在 使用更多起点 中发现的极小值相比,本次运行发现了更好(更小)的极小值,并且成功运行的百分比更高。

另请参阅

主题