2018/11/1更新:
- qpOASES采用的是可行集策略
- 要求H为正定(半正定)矩阵
- 规模较大时耗时较长
动机
做毕设的时候需要求一个这样的二次型最优化问题:
查过资料后得知可以运用罚函数内点法来解决,但是自己写的代码一直效果不是很理想,于是上网搜了一下二次型最优化的C++库,找了很久终于找到了一个专门处理二次型问题的库,qpOASES,特此记录。
下载
开源项目主页:https://projects.coin-or.org/qpOASES/wiki,
点击Download进入下载界面,选择对应项目下载即可,
这里我我下载的是qpOASES-3.2.1.zip。
编译
工具:CMake + VS2015
首先将qpOASES-3.2.1.zip解压缩,然后用CMake进行编译:
Where is the source code
选择项目根目录,即\qpOASES-3.2.1\qpOASES-3.2.1
,在这个目录下有CMakeLists.txt
文件。
Where to build the binaries
随便指定一个路径,如.\qp
,用来存放编译后的文件。
然后点击两次Configure
,一次Generate
,生成包含如下文件的文件夹:
在VS2015中打开ALL_BUILD.vcxproj
,右键ALL_BUILD
->生成
,生成成功后退出,发现\qp\libs\Debug\
路径下生成了qpOASES.lib
,这就是我们需要的库文件(这里要注意平台,如果生成的是x64下的lib,使用的时候就要选择x64平台。
将qpOASES.lib
和头文件拷贝到需要的位置,在VS2015中修改库路径和头文件路径,则完成配置。
测试
官方测试代码:
#include "include\qpOASES.hpp"
int main()
{
USING_NAMESPACE_QPOASES
/* Setup data of first QP. */
real_t H[2 * 2] = { 1.0, 0.0, 0.0, 0.5 };
real_t A[1 * 2] = { 1.0, 1.0 };
real_t g[2] = { 1.5, 1.0 };
real_t lb[2] = { 0.5, -2.0 };
real_t ub[2] = { 5.0, 2.0 };
real_t lbA[1] = { -1.0 };
real_t ubA[1] = { 2.0 };
/* Setup data of second QP. */
real_t g_new[2] = { 1.0, 1.5 };
real_t lb_new[2] = { 0.0, -1.0 };
real_t ub_new[2] = { 5.0, -0.5 };
real_t lbA_new[1] = { -2.0 };
real_t ubA_new[1] = { 1.0 };
/* Setting up QProblem object. */
QProblem example(2, 1);
/* Solve first QP. */
int_t nWSR = 10;
example.init(H, g, A, lb, ub, lbA, ubA, nWSR);
/* Solve second QP. */
nWSR = 10;
example.hotstart(g_new, lb_new, ub_new, lbA_new, ubA_new, nWSR);
/* Get and print solution of second QP. */
real_t xOpt[2];
example.getPrimalSolution(xOpt);
printf("\n xOpt = [ %e, %e ]; objVal = %e\n\n",
xOpt[0], xOpt[1], example.getObjVal());
return 0;
}
运行结果:
运行结果
注意事项
-
real_t
的定义为typedef double
; -
H
是对称的正定(半正定)矩阵; - 使用时注意平台,x86和x86对应,x64和x64对应,否则会报
error LNK2019: 无法解析的外部符号
错误.
网友评论