当求解器失败时
太多的迭代或函数计算
求解器停止,因为在将目标最小化到所要求的公差之前,它达到了迭代次数或函数计算的限制。要继续,请尝试以下一个或多个方法。
1.启用迭代显示 |
2.放宽公差 |
3.从不同的点开始求解器 |
4.检查目标和约束函数定义 |
5.把你的问题集中起来并扩大 |
6.提供梯度或雅可比矩阵 |
7.提供黑森 |
1.启用迭代显示
设置显示
选项“通路”
.此设置显示求解器迭代的结果。
在MATLAB中实现迭代显示®命令行,输入
Options = optimoptions('solvername”、“显示”、“iter”);
调用解算器选项
结构。
有关迭代显示的示例,请参见解释结果.
在迭代显示中寻找什么
看看目标函数(
Fval
或f (x)
或Resnorm
)减少。减少表示进步。检查约束违反(
马克斯约束
),以确保其向0
.减少表示进步。看看一阶最优性是否减小到
0
.减少表示进步。看看是否
信赖域半径
减小到一个小值。这种减少表明目标可能并不顺利。
该怎么做
如果求解器似乎在前进:
集
MaxIterations
和/或MaxFunctionEvaluations
到大于默认值的值。您可以在求解器的函数参考页中的Options表中看到默认值。从最后一个计算点开始求解。
如果求解器没有进展,请尝试其他列出的建议。
2.放宽公差
如果StepTolerance
或OptimalityTolerance
,例如,太小,求解器可能无法识别它已经达到最小值;它可以无限地进行无用的迭代。
若要在命令行更改容差,请使用optimoptions
如在设置和更改选项.
的FiniteDifferenceStepSize
选择(或DiffMaxChange
而且DiffMinChange
选项)会影响求解器的进程。这些选项控制步长在有限差分的导数估计。
3.从不同的点开始求解器
看到改变起始点.
4.检查目标和约束函数定义
例如,检查你的目标和非线性约束函数是否在某些点返回正确的值。看到检查你的目标和约束函数.检查一个不可行的点不会在你的函数中导致错误;看到迭代可能会违反约束.
5.把你的问题集中起来并扩大
当每个坐标对目标和约束函数的影响大致相同时,求解器的运行更加可靠。将您的坐标方向与适当的标量相乘,以平衡每个坐标的效果。添加适当的值到特定的坐标,以平衡它们的大小。
示例:定心和缩放。考虑最小化1e6*x(1)²+ 1e-6*x(2)²
:
F = @(x) 10^6*x(1)^2 + 10^-6*x(2)^2;
最小化f
使用fminunc
“拟牛顿”
算法:
opts = optimoptions('fminunc','显示','none','算法','准牛顿');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],opts) 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],opts) w = 0 0 %正确答案
6.提供梯度或雅可比矩阵
如果不提供梯度或雅可比矩阵,解算器通过有限差分估计梯度和雅可比矩阵。因此,提供这些导数可以节省计算时间,并可以提高精度。基于问题的方法可以自动提供梯度;看到优化工具箱中的自动区分.
对于有约束的问题,提供梯度还有另一个优势。求解器可以到达一个点x
这样x
是可行的,但差分是有限的x
总是会导致一个不可行的点。在这种情况下,求解器可能会失败或过早停止。提供一个梯度可以让求解器继续进行。
在文件中为目标函数和非线性约束函数提供梯度或雅可比矩阵。详细的语法请参见标量目标函数的编写,向量和矩阵目标函数的书写,非线性约束.
要检查梯度函数或雅可比函数是否正确,请使用CheckGradients
选项,如检验梯度或雅可比矩阵的有效性.
如果您拥有Symbolic Math Toolbox™许可证,则可以通过编程方式计算梯度和黑森。有关示例,请参见计算梯度和黑森使用符号数学工具箱.
有关使用梯度和雅可比矩阵的示例,请参见最小化与梯度和黑森,带有梯度的非线性约束,计算梯度和黑森使用符号数学工具箱,求解不含雅可比矩阵的非线性方程组,具有雅可比矩阵的大型稀疏非线性方程组.有关基于问题的方法中的自动区分,请参见自动微分在基于问题的优化中的作用.
7.提供黑森
当您提供Hessian时,求解器通常运行得更可靠,迭代次数更少。
以下求解器和算法接受黑森:
fmincon
内点
.写出黑森函数作为一个单独的函数。有关示例,请参见fmincon内点算法与解析Hessian.fmincon
trust-region-reflective
.给出Hessian作为目标函数的第三个输出。有关示例,请参见密结构黑森最小化,线性等式.fminunc
信赖域
.给出Hessian作为目标函数的第三个输出。有关示例,请参见最小化与梯度和黑森.
如果您拥有Symbolic Math Toolbox许可证,则可以通过编程方式计算梯度和黑森。有关示例,请参见计算梯度和黑森使用符号数学工具箱.要在基于问题的方法中提供Hessian,请参见基于问题的工作流程中的供给导数.
收敛到一个不可行的点
通常,你得到这个结果是因为解算器无法找到一个满足所有约束的点ConstraintTolerance
宽容。然而,求解器可能已经定位或开始于一个可行点,并收敛到一个不可行点。如果解算器失去可行性,请参见解算器丧失可行性.如果quadprog
返回此结果,参见收敛到一个不可行的点
要在求解器找不到可行点时继续进行,请尝试以下一个或多个方法。
1.检查线性约束 |
2.检查非线性约束 |
1.检查线性约束
试着通过求解线性规划问题来找到一个满足边界和线性约束的点。
定义一个目标函数总是零的线性规划问题:
F = 0 (size(x0));%假设x0是初始点
求解线性规划问题,看是否存在可行点:
xnew = linprog(f,A,b,Aeq,beq,lb,ub);
如果有一个可行点
xnew
,使用xnew
作为初始点,并重新运行您原来的问题。如果没有可行点,你的问题就没有很好地阐述。检查边界和线性约束的定义。有关检查线性约束的详细信息,请参见调查线性不可行性.
2.检查非线性约束
在确保你的边界和线性约束是可行的(包含一个满足所有约束的点)之后,检查你的非线性约束。
将目标函数设为零:
@ (x) 0
以所有约束条件和零目标运行优化。如果你找到一个可行点
xnew
,设置X0 = xnew
然后重新运行原来的问题。如果使用零目标函数找不到可行点,则使用带有几个初始点的零目标函数。
如果你找到一个可行点
xnew
,设置X0 = xnew
然后重新运行原来的问题。如果你找不到一个可行的点,尝试使用
fmincon
与EnableFeasibilityMode
选项设置为真正的
和SubproblemAlgorithm
选项设置为“重心”
如采用可行性模式获取解决方案.尝试使用这些选项的几个初始点。如果您仍然没有找到一个可行的点,尝试放松约束,下面讨论。
试着放松你的非线性不等式约束,然后收紧它们。
改变非线性约束函数
c
返回c -
Δ,其中Δ是一个正数。此更改使您的非线性约束更容易满足。使用原始目标函数或零目标函数,为新的约束函数寻找一个可行点。
如果你找到一个可行点,
减少Δ
从先前找到的点开始,为新的约束函数寻找一个可行点。
如果你没有找到一个可行的点,试着增加Δ,然后再看一次。
如果你找不到可行点,你的问题可能真的不可行,这意味着不存在解决方案。再次检查所有约束定义。
解算器丧失可行性
如果求解器开始于一个可行点,但收敛到一个不可行点,尝试以下技术。
试试不同的算法。的
fmincon
“sqp”
而且“内点”
算法通常是最健壮的,所以先尝试其中一种或两种。收紧边界。给予最高的奖励
磅
和最低乌兰巴托
向量可以。这有助于求解器保持可行性。的fmincon
“sqp”
而且“内点”
算法在每次迭代中都服从边界,因此严格的边界有助于整个优化过程。
quadprog
收敛到一个不可行的点
通常,您会得到这个消息,因为线性约束是不一致的,或者几乎是奇异的。为了检查可行点是否存在,创建一个具有相同约束条件且目标函数向量为零的线性规划问题f
.使用linprog
对偶单纯形的
算法:
选项= optimoptions(“linprog”,“算法”,对偶单纯形的);x = linprog(f,A,b,Aeq,beq,lb,ub,options)
如果linprog
找不到可行点,那么你的问题就真的是不可行的。
如果linprog
找到一个可行的点,然后尝试不同的点quadprog
算法。或者,改变一些公差,如StepTolerance
或ConstraintTolerance
再次解决问题。
问题的
求解器到达目标函数小于目标极限容差的点。
你的问题可能真的是无限的。换句话说,这是一个点序列x我与
limf(x我) = -∞。
这样所有的x我满足问题约束条件。
检查你的问题是否正确表述。求解者试图最小化目标函数;如果你想要一个最大值,把你的目标函数改为负值。有关示例,请参见最大化目标.
试着缩放或集中你的问题。看到把你的问题集中起来并扩大.
通过使用,放宽客观极限公差
optimoptions
降低的价值ObjectiveLimit
宽容。
fsolve解不出方程
fsolve
会因为各种原因解不出方程。以下是一些如何进行的建议:
试一试改变起始点.
fsolve
依赖于初始点。通过给它不同的初始点,你增加了成功的机会。检查一下方程的定义,确保它是流畅的。
fsolve
对于具有不连续梯度(如绝对值)的方程可能无法收敛。fsolve
对于具有不连续的函数可能无法收敛。检查方程是否“平方”,即输入和输出的维度相等(与方程的值具有相同数量的未知数)。
特别是改变容差
OptimalityTolerance
而且StepTolerance
.如果您试图通过将公差设置为非常小的值来获得高精度,fsolve
收敛失败。如果你设置的容差太高,fsolve
不能准确地解出方程。检查问题定义。有些问题没有真正的解决办法,例如
X ^2 + 1 = 0
.如果你能接受一个复杂的解决方案,试着将初始点设置为一个复杂的值。fsolve
当起始点是实数时,不试图找到一个复杂的解。