主要内容

当求解器失败时

太多的迭代或函数计算

求解器停止,因为在将目标最小化到所要求的公差之前,它达到了迭代或函数计算的数量的限制。要继续,请尝试以下一个或多个方法。

1.启用迭代显示
2.放宽公差
3.从不同的点开始求解
4.检查目标和约束函数定义
5.集中和扩大你的问题
6.提供梯度或雅可比矩阵
7.提供黑森

1.启用迭代显示

设置显示选项“通路”.此设置显示求解器迭代的结果。

在MATLAB中启用迭代显示®命令行,输入

Options = optimoptions('solvername”、“显示”、“iter”);

调用求解器选项结构。

有关迭代显示的示例,请参见解释结果

在迭代显示中寻找什么

  • 看看目标函数(Fvalf (x)Resnorm)减少。递减表示进度。

  • 检查约束违反情况(马克斯约束),以确保其减少到0.递减表示进度。

  • 看看一阶最优性是否下降到0.递减表示进度。

  • 看看信赖域半径减小到一个小值。这一下降表明,实现这一目标可能并不顺利。

怎么做

  • 如果求解器似乎在进展:

    1. MaxIterations和/或MaxFunctionEvaluations到大于默认值的值。您可以在求解器的函数引用页中的Options表中看到默认值。

    2. 从最后一个计算点开始求解。

  • 如果解算器没有进展,请尝试列出的其他建议。

2.放宽公差

如果StepToleranceOptimalityTolerance,例如,太小,求解器可能无法识别它已达到最小值;它可以无限地进行无意义的迭代。

若要在命令行更改公差,请使用optimoptions如在设置和更改选项

FiniteDifferenceStepSize选择(或DiffMaxChange而且DiffMinChange选项)会影响求解程序的进度。这些选项控制微分估计有限差分的步长。

3.从不同的点开始求解

看到改变起始点

4.检查目标和约束函数定义

例如,检查您的目标和非线性约束函数在某些点返回正确的值。看到检查你的目标和约束函数.检查不可行点不会导致函数出错;看到迭代可能会违反约束

5.集中和扩大你的问题

当每个坐标对目标函数和约束函数的影响差不多时,求解器运行得更可靠。将坐标方向与适当的标量相乘,以平衡每个坐标的效果。为某些坐标添加适当的值以使其大小相等。

示例:定心和缩放。考虑最小化1e6*x(1)²+ 1e-6*x(2)²

F = @(x) 10^6*x(1)²+ 10^-6*x(2)²;

最小化f使用fminunc“拟牛顿”算法:

opts = optimoptions('fminunc','Display','none','Algorithm','准牛顿');X = fminunc(f,[0.5;0.5],opts) X = 0 0.5000

结果是不正确的;差的缩放影响了得到好的解。

衡量问题的规模。集

D = diag([1e-3,1e3]);fr = @(y) f(D*y);Y = fminunc(fr, [0.5;0.5], opts) Y = 0 0 %正确答案

同样,定心不良也会影响解决方案。

Fc = @(z)fr([z(1)-1e6;z(2)+1e6]);定心不良z = fminunc(fc,[。]5 .5],选项)z = 1.0e+005 * 10.0000 -10.0000 %看起来不错,但是……Z - [1e6 -1e6] %检查Z与1e6 ans的距离= -0.0071 0.0078 %显示距离FCC = @(w)fc([w(1)+1e6;w(2)-1e6]);%居中w = fminunc(fcc,[。]5 .5],选项)w = 0 %正确答案

6.提供梯度或雅可比矩阵

如果不提供梯度或雅可比矩阵,求解者通过有限差分估计梯度和雅可比矩阵。因此,提供这些导数可以节省计算时间,并可以提高精度。基于问题的方法可以自动提供梯度;看到优化工具箱中的自动区分

对于有约束的问题,提供梯度还有另一个好处。解算器可以达到一个点x这样x是可行的,但有限的差异围绕x总是引到一个不可行的点。在这种情况下,求解器可能会失败或过早停止。提供梯度允许求解器继续进行。

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

要检查梯度函数或雅可比矩阵函数是否正确,请使用CheckGradients选项,如中所述检验梯度或雅可比矩阵的有效性

如果您有Symbolic Math Toolbox™许可证,您可以通过编程的方式计算梯度和hessian。示例请参见使用符号数学工具箱计算梯度和黑森斯

有关使用梯度和雅可比矩阵的例子,请参见用梯度和黑森极小化,带有梯度的非线性约束,使用符号数学工具箱计算梯度和黑森斯,求解不含雅可比矩阵的非线性方程组,具有雅可比矩阵的大型稀疏非线性方程组.有关基于问题的方法中的自动区分,请参见自动区分在基于问题优化中的作用

7.提供黑森

当您提供Hessian时,求解器通常运行得更可靠,迭代次数更少。

以下求解器和算法接受hessian:

如果您有“符号数学工具箱”许可,则可以以编程的方式计算梯度和黑森函数。示例请参见使用符号数学工具箱计算梯度和黑森斯.要在基于问题的方法中提供Hessian,请参见基于问题的工作流中的供应派生

收敛到一个不可行的点

通常,得到这个结果是因为求解器无法找到满足所有约束的点ConstraintTolerance宽容。然而,求解器可能已经定位或开始于一个可行点,并收敛到一个不可行的点。如果解算器失去了可行性,请参见求解器丢失可行性.如果quadprog返回此结果,请参见quadprog收敛到一个不可行的点

若要在求解器找不到可行点时继续,请尝试以下一个或多个方法。

1.检查线性约束
2.检查非线性约束

1.检查线性约束

试着通过求解线性规划问题找到一个满足边界和线性约束的点。

  1. 定义一个目标函数总是为零的线性规划问题:

    F = 0 (size(x0));%假设x0是起始点
  2. 解决线性规划问题,看看是否有一个可行点:

    xnew = linprog(f,A,b,Aeq,beq,lb,ub);
  3. 如果有一个可行的点xnew,使用xnew作为初始点,重新运行你原来的问题。

  4. 如果没有可行点,说明你的问题没有很好地表述。检查边界和线性约束的定义。有关检查线性约束的详细信息,请参见研究线性不可行性

2.检查非线性约束

在确保边界和线性约束是可行的(包含一个满足所有约束的点)之后,检查非线性约束。

  • 将目标函数设为零:

    @ (x) 0

    在所有约束条件下运行优化,目标为零。如果你找到一个可行点xnew,设置X0 = xnew然后重新运行原来的问题。

  • 如果使用零目标函数找不到可行点,可以使用带有多个初始点的零目标函数。

    • 如果你找到一个可行点xnew,设置X0 = xnew然后重新运行原来的问题。

    • 如果你找不到一个可行的点,试着用fminconEnableFeasibilityMode选项设置为真正的SubproblemAlgorithm选项设置为“重心”,如通过可行性模式获取解决方案.对这些选项尝试几个初始点。

    • 如果您仍然没有找到一个可行的点,试着放松约束,接下来讨论。

试着放松你的非线性不等式约束,然后收紧它们。

  1. 改变非线性约束函数c返回c -Δ,其中Δ是一个正数。此更改使您的非线性约束更容易满足。

  2. 为新的约束函数寻找一个可行点,可以使用原始目标函数,也可以使用零目标函数。

    1. 如果你找到一个可行点,

      1. 减少Δ

      2. 从先前找到的点开始,为新的约束函数寻找一个可行的点。

    2. 如果您没有找到一个可行的点,尝试增加Δ并再次查看。

如果您没有找到可行点,那么您的问题可能是真正不可行的,这意味着不存在解决方案。再次检查所有约束定义。

求解器丢失可行性

如果解算器从一个可行点开始,但收敛到一个不可行的点,请尝试以下技术。

  • 尝试不同的算法。的fmincon“sqp”而且“内点”算法通常是最健壮的,所以首先尝试一种或两种算法。

  • 收紧界限。给予最高的和最低乌兰巴托可以的向量。这可以帮助求解器保持可行性。的fmincon“sqp”而且“内点”算法在每次迭代时都遵守边界,因此严格的边界有助于整个优化过程。

quadprog收敛到一个不可行的点

通常,你得到这个消息是因为线性约束是不一致的,或者是接近奇异的。为了检验一个可行点是否存在,创建一个具有相同约束且目标函数向量为零的线性规划问题f.使用linprog对偶单纯形的算法:

选项= optimoptions(“linprog”,“算法”,对偶单纯形的);x = linprog(f,A,b,Aeq,beq,lb,ub,options)

如果linprog找不到可行点,那么你的问题就真的是不可行的。

如果linprog找到一个可行的点,然后尝试不同的点quadprog算法。或者,改变一些公差,如StepToleranceConstraintTolerance然后再解决问题。

问题的

求解器到达一个目标函数小于目标极限公差的点。

  • 你的问题可能真的是无限的。换句话说,有一个点的序列x

    limfx) = -∞。

    这样所有的x满足问题约束条件。

  • 检查你的问题是否表述正确。求解者试图最小化目标函数;如果你想要一个最大值,把目标函数改为负数。示例请参见目标最大化

  • 试着扩大或集中你的问题。看到集中和扩大你的问题

  • 通过使用放宽客观极限公差optimoptions的值ObjectiveLimit宽容。

fsolve不能解方程

fsolve可能因为各种原因解不出一个方程。下面是一些如何进行的建议:

  1. 试一试改变起始点fsolve依赖于一个初始点。通过给它不同的初始点,你增加了成功的机会。

  2. 检查方程的定义,以确保它是平滑的。fsolve对于具有不连续梯度的方程,例如绝对值,可能无法收敛。fsolve对于不连续的函数不能收敛。

  3. 检查方程是否为“正方形”,这意味着输入和输出的维度相等(具有与方程值相同的未知数数量)。

  4. 特别是改变公差OptimalityTolerance而且StepTolerance.如果您试图通过将公差设置为非常小的值来获得较高的精度,fsolve能不能收敛。如果你设置的公差太高,fsolve不能准确地解出方程。

  5. 检查问题定义。有些问题没有真正的解决办法,比如X ^2 + 1 = 0.如果您可以接受一个复杂的解决方案,尝试将初始点设置为一个复杂的值。fsolve当初始点是实数时,不尝试寻找复解。

相关的话题

Baidu
map