用于Matlab的一般非凸/非线性约束问题(NLP)求解器的包装器

时间:2016-04-22 00:42:30

标签: matlab mathematical-optimization nonlinear-optimization

我有一般的非凸函数,具有一般的非凸不等式约束。我有一个可行的起点,我想在限制条件下尽量减少能量。解算器不应该离开可行域(即屏障方法),并且永远不应该增加能量。到目前为止,我使用的fmincon在两个帐户上都失败了,我想要一个简单的方法来尝试其他求解器,如IPOPT,KNITRO和SNOPT。 说到这一点,我不介意建议一个能够完成我正在寻找的特定求解器(不增加并保持在可行区域内)。

我想尝试其他求解器,但我正在寻找在某个包装器上对问题进行建模(例如yalmip和cvx用于凸优化; AMPL怎么样?),这会将其转换为其他求解器(或者只是调用我的函数并将它们的输出转换为每个求解器所需的 - 即我想使用单个接口。 为了在代码方面尽可能灵活,我更愿意为目标和约束函数及其渐变提供回调函数(用Matlab编写),这将返回实际值。当然,如果有一个选项可以使用内部变量来提供像auto-diff这样的东西,而不会影响代码的灵活性,那就太好了(我有一个复杂的代码,并且对一些特殊的变量类型友好会是一个麻烦)。 我没有尝试过,但如果它足够灵活,我不会介意使用.nl文件,虽然我需要一些关于管道的提示来与我的matlab代码接口(运行一些请求解决问题的应用程序)问题 - 即它提供了一个输入并期望来自某些求解器函数的解决方案,如fmincon)。

顺便说一下,我对fmincon()的问题是,在某些时候它开始增加函数并且可以以更坏的点(更大的目标)结束,并且如果过早终止则会破坏约束(它似乎不是收敛)。

1 个答案:

答案 0 :(得分:1)

我使用了一些求解器和建模软件包,重点是Matlab。

  • 首先,似乎内点法的定义相当宽松。所有求解器都允许自己进入不可行区域(即表现得像惩罚方法),而wiki用一个包含约束的日志函数非常清楚地描述了一个屏障方法:

https://en.wikipedia.org/wiki/Interior_point_method

因此,当我想严格解决我的问题时(为了保持可行域),我定义了自己的f_aggregate()用日志包装我的约束,并仅使用求解器来绑定变量范围(或者只是使用无约束求解器。)

  • Yalmip非常方便。您定义NLP问题的方式与使用跟踪操作的sdpvar定义凸问题的方式相同,我假设它创建了一个类似于auto-diff包的模型。缺点:

    1. 代码需要与sdpvar兼容,因此需要付出一些努力,例如,替换bsxfun()调用或将赋值替换为double矩阵。另一方面,无需提供衍生品。
    2. 它不能很好地扩展。在一个小问题上,它运行良好,但在一个小问题上,它运行了将近一个小时,其中一半的时间花在配方上(例如处理电源操作似乎很昂贵)。 这对我来说意味着,与向mosek提供模型不同,它为IPOPT提供了一个慢回调(类似于auto-diff)(但我可能错了)。我无法看到IPOPT所做的迭代。 我的相关帖子: https://groups.google.com/forum/?fromgroups#!searchin/yalmip/zohar/yalmip/eJidaJgI9ec/0KqI-KP4LwAJ
  • OptiToolbox更低级别,允许回调,而且它更符合我的要求。但似乎NLP唯一有用的支持解算器是IPOPT。公平地说,其他有趣的解决方案是商业性的。 它还可以使用SCIP编写.gms文件,该文件可以由GAMS执行或由GAMS导出到AMPL。不幸的是,我的具体问题没有正确编写,并且两个软件包在导出的问题上产生了相同的错误结果。

  • 我使用了AMPL(和GAMS看起来相似)。它不是那么直观,问题的表达水平相当低(例如没有规范函数或其他甜味剂),转换我的matlab代码或基于它为AMPL生成问题似乎很痛苦(我自己) 。此外,演示版本将问题限制为有趣求解器的10个变量。

  • 我想尝试一些商业解决方案,比如Knitro和Snopt。它们都有6个月的试用期,但它们仅限于300个变量。我不确定如何在限制为300个变量的大规模问题上测试解算器。 更新:Knitro还有一个完整的月试用版,我可以试试。

  • Tomlab看起来很有趣。它是一个类似于OptiToolbox的商业软件包,可以与商业解决方案进行交互。我等着他们用许可证回复,但是会限制21天。

  • 我认为有在线服务器,可以尝试商业解算器。但我需要一个出色的出口商(例如)GAMS或AMPL格式。

  • 总而言之,Matlab的fmincon看起来并不那么糟糕。虽然只有内部点可以处理大规模问题,但它似乎至少与IPOPT一样好(当我的目标函数返回Inf拒绝解决方案时,它似乎当前有一个错误)。 由于NLP问题一般都很难,我想我不应该期待像Mosek这样的神奇解算器。

更新:我碰巧尝试了Knitro和Snopt(完整版)。 Knitro的matlab界面非常棒。它与fmincon完全一样,实现了相同算法的稀疏更健壮的版本。 Snopt的fmincon界面很笨重。我不得不修补它以增加雅各比的稀疏性,并且返回的雅各比人被调换,我花了很多时间来抓住它,因为它因为每一个小错误而崩溃了matlab。 就我的问题表现而言,Knitro在我的一个小问题上出人意料地失败了,而且两个解决方案一般都没有比其他解决方案做得更好(运行数小时没有收敛)。

UPDATE2:我尝试下面的Erwin Kalvelagen为每个不等式约束添加一个变量,用等式约束(ineq = new var)替换不等式约束,并绑定var。 fmincon尊重这些界限,但它并不是一个神奇的解决方案而且解算器很早就被卡住了;此外,IPOPT和Knitro并不尊重eq界限并进入不可行区域。