Main Content

当求解器可能成功求解时

终点等于初始点

初始点可能是一个局部最小值或解,因为一阶最优性测度接近于 0。您可能对此结果不满意,因为求解器并未改进您的初始点。

如果您不确定初始点是否确实为局部最小值,请尝试:

  1. 从不同点开始 - 请参阅更改初始点

  2. 检查您的目标和约束是否正确定义(例如,它们在某些点处是否返回了正确的值?)- 请参阅检查您的目标函数和约束函数。检查以确保不可行点不会导致函数中出现错误;请参阅迭代可能违反约束

  3. 更改容差,例如 OptimalityToleranceConstraintToleranceStepTolerance - 请参阅使用适当的容差

  4. 缩放您的问题,使每个坐标具有大致相同的影响 - 请参阅重新缩放问题

  5. 提供梯度和黑塞矩阵信息 - 请参阅提供解析梯度或雅可比矩阵提供黑塞矩阵

可能是局部最小值

求解器可能已达到局部最小值,但无法确定,因为一阶最优性测度不小于 OptimalityTolerance 容差。(要了解有关一阶最优性测度的更多信息,请参阅一阶最优性测度。)要查看报告的解是否可靠,请考虑以下建议。

1.非平滑函数
2.以终点作为起点重新执行优化
3.尝试不同算法
4.更改容差
5.重新缩放问题
6.检查附近的点
7.更改有限差分选项
8.提供解析梯度或雅可比矩阵
9.提供黑塞矩阵

1.非平滑函数

如果您尝试最小化非平滑函数,或具有非平滑约束,“可能是局部最小值”也许是最好的退出消息。这是因为,一阶最优性条件不适用于非平滑点。

为了让自己确信该解是充分的,请尝试检查附近的点

2.以终点作为起点重新执行优化

如果在终点处重新开始优化,则可以生成具有更好的一阶最优性测度的解。更好(较低)的一阶最优性测度让您更有理由相信解是可靠的。

例如,假设有以下最小化问题,摘自示例Using Symbolic Mathematics with Optimization Toolbox Solvers

options = optimoptions('fminunc','Algorithm','quasi-newton');
funh = @(x)log(1 + (x(1) - 4/3)^2 + 3*(x(2) - (x(1)^3 - x(1)))^2);
[xfinal fval exitflag] = fminunc(funh,[-1;2],options)

Local minimum possible.

fminunc stopped because it cannot decrease the 
objective function along the current search direction.

xfinal =
    1.3333
    1.0370

fval =
  8.5265e-014

exitflag =
     5

退出标志值 5 表示一阶最优性测度大于函数容差。从 xfinal 开始再次运行最小化:

[xfinal2 fval2 exitflag2] = fminunc(funh,xfinal,options)

Local minimum found.

Optimization completed because the size of the gradient is 
less than the default value of the function tolerance.

xfinal2 =
    1.3333
    1.0370

fval2 =
  6.5281e-014

exitflag2 =
     1

局部最小值是“找到”,而不是“可能”,exitflag 为 1 而不是 5。这两个解实际上相同。然而,第二次运行有更令人满意的退出消息,因为一阶最优性测度相当低,是 7.5996e-007,而不是 3.9674e-006

3.尝试不同算法

许多求解器都允许您选择算法。不同的算法可能会导致使用不同的停止条件。

例如,以终点作为起点重新执行优化会返回第一次运行时的 exitflag 5。这次运行使用 quasi-newton 算法。

信赖域算法需要用户提供的梯度。betopt.m 包含目标函数和梯度的计算:

function [f gradf] = betopt(x)

g = 1 + (x(1)-4/3)^2 + 3*(x(2) - (x(1)^3-x(1)))^2;
f = log(g);
gradf(1) = 2*(x(1)-4/3) + 6*(x(2) - (x(1)^3-x(1)))*(1-3*x(1)^2);
gradf(1) = gradf(1)/g;
gradf(2) = 6*(x(2) - (x(1)^3 -x(1)))/g;

使用 trust-region 算法运行优化会生成不同的 exitflag:

options = optimoptions('fminunc','Algorithm','trust-region','SpecifyObjectiveGradient',true);
[xfinal3 fval3 exitflag3] = fminunc(@betopt,[-1;2],options)

Local minimum possible.

fminunc stopped because the final change in function value 
relative to its initial value is less than the default value 
of the function tolerance.

xfinal3 =
    1.3333
    1.0370

fval3 =
  7.6659e-012

exitflag3 =
     3

退出条件优于 quasi-newton 条件,尽管前者仍不是最佳条件。从终点重新运行该算法会产生更好的点,其一阶最优性测度极小:

[xfinal4 fval4 eflag4 output4] = fminunc(@betopt,xfinal3,options)

Local minimum found.

Optimization completed because the size of the gradient is 
less than the default value of the function tolerance.

xfinal4 =

    1.3333
    1.0370

fval4 =
     0

eflag4 =
     1

output4 = 
         iterations: 1
          funcCount: 2
       cgiterations: 1
      firstorderopt: 7.5497e-11
          algorithm: 'trust-region'
            message: 'Local minimum found.

Optimization completed because the size o...'
    constrviolation: []

4.更改容差

有时,收紧或放松容差会产生更令人满意的结果。例如,在尝试不同算法部分中选择较小的 OptimalityTolerance 值:

options = optimoptions('fminunc','Algorithm','trust-region',...
    'OptimalityTolerance',1e-8,'SpecifyObjectiveGradient',true); % default=1e-6
[xfinal3 fval3 eflag3 output3] = fminunc(@betopt,[-1;2],options)

Local minimum found.

Optimization completed because the size of the gradient is 
less than the selected value of the function tolerance.

xfinal3 =
    1.3333
    1.0370

fval3 =
     0

eflag3 =
     1

output3 = 
         iterations: 15
          funcCount: 16
       cgiterations: 12
      firstorderopt: 7.5497e-11
          algorithm: 'trust-region'
            message: 'Local minimum found.

Optimization completed because the size...'
    constrviolation: []

fminunc 比以前多进行了一次迭代,但得到的解更好。

5.重新缩放问题

尝试通过缩放和中心化,让每个坐标对目标函数和约束函数的影响大致相同。有关示例,请参阅中心化和缩放问题

6.检查附近的点

在接近终点的点处计算您的目标函数和约束(如果它们存在)。如果终点是局部最小值,附近的可行点具有较大的目标函数值。有关示例,请参阅检查附近的点

如果您有 Global Optimization Toolbox 许可证,请尝试从终点运行 patternsearch (Global Optimization Toolbox) 求解器。patternsearch 会检查附近的点,并接受所有类型的约束。

7.更改有限差分选项

中心有限差分计算起来更费时,但更精确。当您的问题可能有高曲率时,请使用中心差分。

要在命令行中选择中心差分,请使用 optimoptions'FiniteDifferenceType' 设置为 'central',而不是默认值 'forward'

8.提供解析梯度或雅可比矩阵

如果不提供梯度或雅可比矩阵,求解器会通过有限差分来估计梯度和雅可比矩阵。因此,提供这些导数可以节省计算时间,并可以提高准确度。基于问题的方法可以自动提供梯度;请参阅 Automatic Differentiation in Optimization Toolbox

对于约束问题,提供梯度还有另一个优势。求解器可以到达点 x,这说明 x 是可行点,但 x 附近的有限差分总是导致不可行点。在这种情况下,求解器可能会失败或过早停止。提供梯度可允许求解器继续。

在文件中为目标函数和非线性约束函数提供梯度或雅可比矩阵。有关语法的详细信息,请参阅编写标量目标函数编写向量和矩阵目标函数非线性约束

要检查梯度或雅可比函数是否正确,请使用 checkGradients 函数,如Checking Validity of Gradients or Jacobians中所述。

如果您有 Symbolic Math Toolbox™ 许可证,您可以通过编程方式计算梯度和黑塞矩阵。有关示例,请参阅Calculate Gradients and Hessians Using Symbolic Math Toolbox

有关使用梯度和雅可比矩阵的示例,请参阅使用梯度和黑塞矩阵的最小化带梯度的非线性约束Calculate Gradients and Hessians Using Symbolic Math Toolbox求解不含和含雅可比矩阵的非线性方程组Large Sparse System of Nonlinear Equations with Jacobian。对于基于问题的方法中的自动微分,请参阅Effect of Automatic Differentiation in Problem-Based Optimization

9.提供黑塞矩阵

当您提供黑塞矩阵时,求解器的运行通常更可靠,迭代次数也更少。

以下求解器和算法接受黑塞矩阵:

如果您有 Symbolic Math Toolbox 许可证,您可以通过编程方式计算梯度和黑塞矩阵。有关示例,请参阅Calculate Gradients and Hessians Using Symbolic Math Toolbox。要在基于问题的方法中提供黑塞矩阵,请参阅Supply Derivatives in Problem-Based Workflow

Calculate Gradients and Hessians Using Symbolic Math Toolbox中的示例说明 fmincon 在没有黑塞矩阵的情况下进行 77 次迭代,但在有黑塞矩阵的情况下只进行 19 次迭代。