CVX介绍——求解器

来源:互联网 发布:钢管舞教学视频软件 编辑:程序博客网 时间:2024/06/03 20:25

这个版本的CVX支持四个解算器,每个解算器都有不同的功能:这里写图片描述
每个求解器都有不同的功能和不同的性能级别。 例如,SeDuMi [Stu99],SDPT3 [TTT03]和MOSEK 7支持CVX本身支持的所有连续(非整数)模型,而Gurobi则更有限,因为它不支持半确定性约束。 GLPK进一步受到限制。 另一方面,Gurobi,GLPK,和MOSEK支持整数的consraints,而SeDuMi和SDPT3则不支持。

在本使用指南中,我们已经创建了特别的章节,介绍如何在CVX上使用Gurobi和MOSEK:
Gurobi:在CVX上使用Gurobi http://web.cvxr.com/cvx/doc/gurobi.html#gurobi
Mosek:在CVX上使用MOSEK http://web.cvxr.com/cvx/doc/mosek.html#mosek
对GLPK的支持应该被认为是实验性的,并且主要是为了支持即将到来的Octave功能而提供的(尚未就绪)。

选择一个求解器
默认求解器当前是SDPT3。 我们发现SeDuMi对于大多数问题来说速度更快,但不幸的是,它并不可靠。 然而,没有一个解算器是完美的,你可能会发现你的应用程序另一个求解器是首选。

要查看当前选择的解算器,只需键入

cvx_solver

要更改当前求解器,只需按照所选求解器的名称按照cvx_solver。 例如,要选择SeDuMi,请键入

cvx_solver sedumi

cvx_solver命令不区分大小写,所以cvx_solver SeDuMi也能正常工作。

如果在模型中发出这个命令 - 也就是在cvx_begin和cvx_end之间,它将只为该模型改变求解器; 下一个型号将使用之前的选择。 另一方面,如果你在模型之外发出一个cvx_solver命令,它会改变用于Matlab会话剩余部分的解算器(或者直到你再次改变它)。

如果您想要永久更改默认解算器 - 也就是说,即使您退出并重新启动Matlab,它仍然是默认解算器 - 请确保它已正确设置,然后发出命令

cvx_save_prefs

该命令不仅可以保存解算器选项,还可以保存cvx_expert,cvx_power_warning和cvx_precision的设置。

控制屏幕输出
一旦您对使用CVX有信心并开始将其整合到您的大型算法和程序中,您可能会希望将其传递到屏幕的消息静音。 为此,只需将quiet关键字添加到cvx_begin命令; 那是,

cvx_begin quiet    ...cvx_end

先前版本的CVX使用了单独的cvx_quiet命令,如果您愿意,该命令在该版本中仍然可用。 输入cvx_quiet true将取消解算器的屏幕输出,而输入cvx_quiet false将恢复屏幕输出。 如果您在模型中(即在cvx_begin和cvx_end之间)输入这些命令,则只会影响该模型。 如果您在模型之外输入,则会影响所有后续模型。 输入不带参数的cvx_quiet将返回当前设置。

解释结果
输入完整的CVX规范并发出cvx_end命令后,将调用求解器以生成数值结果。 它继续用计算的数值替换模型中的变量,并创建包含目标函数值的变量cvx_optval。 它还以字符串cvx_status的形式总结了其努力的结果。 cvx_status的可能值如下所示:
Solved(解决了)

一个补充(原始和双重)的解决方案已被发现。 原始和双重变量被替换为它们的计算值,并且问题的最优值被放置在cvx_optval(对于可行性问题按照惯例是00)。

Unbounded(无界)

求解者确定问题是无界的。 cvx_optval的值设置为-Inf用于最小化,+ Inf用于最大化。 (可行性问题,通过建设,从来没有产生无限的地位。)任何双重变量的价值取代NaN,因为双重问题实际上是不可行的。对于无限的问题,CVX存储一个无限的方向到问题变量。 这是可行集无界的方向,最优值接近±∞。 重要的是要明白,这个价值很可能不是一个可行的点。 如果要求一个可行的点,那么就应该把这个问题作为一个可行性问题来重新解决,而忽略了目标。 在数学上讲,给定一个无界方向v和一个可行点x,x + tv对于所有t≥0都是可行的,并且客观趋向于-∞(对于最小化; +∞对于最大化)为 t→+∞本身。

Infeasible(不可行)

这个问题已经被证明是不可行的,通过发现一个无限的方向。 变量的值用NaN填充,并且cvx_optval的值被设置为+ Inf以用于最小化和可行性问题,并且用于最大化。与一个可证明的不可行的问题相联系是一个无限的双重方向。 这个方向的适当组件存储在双变量中。 类似于无界的情况,重要的是要明白,无限的双重方向很可能不是一个可行的双重点。

Inaccurate/Solved, Inaccurate/Unbounded, Inaccurate/Infeasible(不准确/已解决,不准确/无界,不准确/不可行)

这三个状态值表明求解器无法确定在默认的数值容差范围内。 但是,它确定所获得的结果满足“宽松”的公差水平,因此可能仍然适合进一步使用。 如果发生这种情况,则应在进一步计算之前使用它来测试计算得到的解决方案的有效性。 请参阅控制精度以获得解算器公差的更高级讨论以及如何进行调整。

Suboptimal(次优)

此状态仅适用于混合整数问题。 当分支算法发现至少有一个可行的整数解决方案时,它被返回,但它无法继续搜索过程到全局最优。 如果求解器因时间限制或强制中断而终止(例如,如果用户键入Ctrl-C),则会发生这种情况。

Failed(失败)

求解器在解决方案方面没有取得足够的进展,甚至在“宽松”的容差范围内。 cvx_optval和原始和双重变量的值用NaN填充。 这个结果可能是由于SeDuMi中的数值问题而发生的,通常是因为这个问题在某种程度上是特别“讨厌”的(例如,一个非零对偶缺口)。

Overdetermined(超定)

预求解器确定问题比变量有更多的等式约束,这意味着等式约束的系数矩阵是奇异的。 在实践中,这样的问题往往,但并非总是不可行的。 不幸的是,求解者通常不能处理这样的问题,所以不能得出确切的结论。 在超定问题中讨论最常产生超定结果的情况。

控制精度

注意:我们认为解算器精度的修改是一个高级功能,要谨慎使用(如果有的话),并且只有在CVX中建立模型后才能使用

凸优化的数值方法不准确; 他们将结果计算到预定义的数值精度或公差范围内。 在解决模型问题时,解算器实现的容差水平将返回到cvx_slvtol变量中。 不建议尝试从任何绝对意义上解释这个容忍度。 首先,每个求解器计算的方式不同。 另一方面,它在很大程度上取决于CVX在将模型交付给求解器之前应用于模型的相当多的转换。 所以尽管你可能会发现它的价值很有趣,但我们强烈建议你不要在你的应用程序中依赖它。
CVX默认选择的容差水平是从一些底层解算器继承而来的,只需稍作修改即可。 CVX实际上考虑了三个不同的公差级别这里写图片描述
求解模型时:

求解器容差εsolverεsolver是求解器要求的水平。 求解器一旦达到这个水平就会停止,或者直到没有进一步的进展。标准公差εstandardεstandard是CVX认为模型解算达到完全精度的水平。降低的容差ε降低的水平是CVX认为模型“不准确”被取消的水平,返回一个带有不准确/前缀的状态。 如果无法实现此容差,则CVX返回失败状态,并且变量的值不应被视为可靠。

通常,εsolver=εstandardεsolver=εstandard,但设置εstandard<εsolverεstandard<εsolver有一个有用的解释:它允许求解器搜索更准确的解决方案,而不会导致不准确/或 失败的条件,如果它不能这样做。 [εsolver,εstandard,εreduced] [εsolver,εstandard,εreduced]的默认值设为[ε1/ 2,ε1/ 2,ε1/ 4] [ε1/ 2,ε1/ 2,ε1/ 4] = 2.22×10-16ε= 2.22×10-16是机器精度。 这对于大多数应用来说应该是足够的。
如果你想修改公差,你可以使用cvx_precision命令。 有三种方法可以调用这个命令。 不带参数调用,它将打印当前的容忍度到屏幕上; 或者如果作为一个函数调用,它将返回一个3元素行向量中的这些级别。
使用字符串参数调用cvx_precision,您可以从一组预定义的精度模式中进行选择:
这里写图片描述
在函数模式下,这些调用看起来像是cvx_precision(’low’)等。注意,最好的精度设置将求解器目标设置为零,这意味着解算器只要能够取得进展就会继续。它通常比默认的要慢,但它也是一样可靠的,有时会产生更准确的解决方案。

最后,可以用标量,长度为2的矢量或长度为3的矢量调用cvx_precision命令。如果将它传递给标量,它将把求解器和标准公差设置为该值,并且将为您计算默认精度降低值。粗略地说,降低的精度将是标准精度的平方根,加上一些界限以确保它保持合理。如果提供两个值,则解算器和标准公差将使用较小的值,对于公差的减小将使用较大的值。如果您提供三个值,它们的值将被排序,并且每个公差将被单独设置。

cvx_precision命令既可以在CVX模型中使用,也可以在其外部使用;其行为在每种情况下都不相同。如果你从模型中调用它,例如,

cvx_begin    cvx_precision high    ...cvx_end

那么您选择的设置将仅适用,直到达到cvx_end。 如果您在模型之外调用它,例如,

cvx_precision highcvx_begin    ...cvx_end

那么你选择的设置将适用于全局; 也就是任何后来创建和解决的模型。 本地方法应该在多个模型的构建和应用中以不同的精度解决。

如果在函数模式下调用cvx_precision,不管是使用字符串还是数值,都将返回前一个精度向量作为输出 - 如果不带任何参数调用,则会得到相同的结果。 这看起来可能会让人感到困惑,但是这样做是为了让您可以将以前的值保存在变量中,并在计算结束时进行恢复。 例如,

cvxp = cvx_precision( 'high' );cvx_begin    ...cvx_endcvx_precision( cvxp );

这被认为是一个较大的应用程序中的良好的编码礼仪,其中可以使用多个精度级别的多个CVX模型。 当然,更简单但同样有礼貌的方法是在CVX模型中调用cvx_precision,如上所述,以便其效果仅持续用于该模型。

高级求解器设置
警告对于那些对所使用的底层解算器有深入了解的用户,或者从解算器的开发人员处获得特定建议以提高性能的用户,这是一个高级主题。 不当使用cvx_solver_settings命令会导致不可预知的结果。
求解器可以通过多种方式进行调整和调整。解决方案供应商试图选择默认设置,以在广泛的问题中提供良好的性能。但是没有解决方法,也没有选择设置,对于每种可能的模型都会表现的很好。在某些情况下,为了改善其特定应用的性能,可能需要特别说明。不幸的是,这种设置不同于求解器和求解器,所以CVX无法以可验证的,可靠的全局方式提供这种能力。

不过,使用新的cvx_solver_settings命令,您可以在特定模型需要时自定义求解器的设置。我们不能强调,这是一个只有经验丰富的建模师才能使用的专家功能。事实上,如果你是一个专家,你明白这些警告是至关重要的:

CVX不检查您提供的设置的正确性。如果解算器拒绝设置,则CVX将会失败,直到您更改或删除这些设置。不能保证改变设置会以任何方式提高性能;事实上,它可能会使表现更糟。CVX Research没有提供每个求解器可用的特定设置的文档;你将不得不咨询解决方案自己的文档。此处设置的设置会覆盖CVX可能为每个求解器选择的默认值。因此,在某些情况下,使用这个功能可能会混淆CVX,导致错误解释结果。出于这个原因,我们不能支持所有可能的自定义设置组合。除非完全关闭解算器输出,否则CVX会在每次解算模型时自定义设置生效。

有了这个警告,让我们介绍一下cvx_solver_settings。

键入

cvx_solver_settings

在命令提示符处提供了为活动解算器提供的自定义设置的列表。自定义设置是特定于每个求解器。键入

cvx_solver_settings -all

将提供所有求解器提供的自定义设置的完整列表。

要为当前解算器创建新的自定义设置,请使用以下语法:

cvx_solver_settings('{name}',{value})

{name}必须是一个有效的MATLAB变量/字段名称。 {value}可以是任何有效的Matlab对象; CVX不会以任何方式检查它的值。

要清除活动解算器的所有自定义设置,请键入

cvx_solver_settings -clear

要清除一个设置,请输入

cvx_solver_settings -clear {<name>}

要清除所有解算器的所有设置,请输入

cvx_solver_settings -clearall

由cvx_solver_settings命令创建的设置与cvx_solver,cvx_precision等具有相同的范围。例如,如果在模型中使用此命令(在cvx_begin和cvx_end之间),则更改将仅应用于该特定模型。如果你在一个特定的模型之外发出这个命令,这个改变将持续到MATLAB会话结束(或者直到你再次改变它)。最后,如果您使用cvx_save_prefs命令,则添加的所有自定义设置将在下次启动Matlab时保存并恢复。