在c++中是否有一个二次规划库?

时间:2022-10-31 05:52:14

The only Google search result I found is QuadProg++ but it can not solve the quadratic programming problem whose matrix is not applicable for Cholesky decomposition.

我发现的唯一谷歌搜索结果是QuadProg++,但它不能解决矩阵不适用于Cholesky分解的二次规划问题。

So can anyone give me some suggestion on other library? Thanks.

那么有人能给我一些关于其他图书馆的建议吗?谢谢。

5 个解决方案

#1


5  

There are several libraries that include QP solvers. There are both open-source and commercial options. The existing answers list a few of these. I'd like to clarify the issue with the matrix.

有几个库包括QP解决程序。有开源和商业选择。现有的答案列出了其中的一些。我想澄清一下这个矩阵的问题。

I assume you are referring to the objective matrix. The constraint matrix only needs to lead to a non-empty feasible set. You mentioned that the matrix is not suitable for Cholesky decomposition. Since the Cholesky decomposition can be formed for any positive definite matrix, the implication is that your matrix is not positive definite.

我假设你指的是客观矩阵。约束矩阵只需要引入一个非空的可行集合,你提到这个矩阵不适合乔列斯基分解。由于Cholesky分解可以形成任何正定矩阵,这意味着你的矩阵不是正定的。

If the matrix is positive semi-definite (i.e. it has one or more zero eigenvalues) then the problem is a convex QP and can be solved efficiently. However, many solvers require a positive definite objective. Since the objective of a positive semi-definite QP has a non-trivial nullspace, there may be many solutions. In fact, the set of solutions can even be unbounded. Numerical algorithms will only give an approximate solution anyways, so it is rarely important that the matrix have eigenvalues that are exactly zero. You can make the matrix positive definite by adding a diagonal matrix with a small positive value on the diagonal. This will essentially select the solution with the smallest 2-norm. In practice, it is a good idea to do this even when the matrix is positive definite because matrices that have eigenvalues close to zero can often cause problems with numerical solvers. How much diagonal to add in is a tradeoff between stability and accuracy.

如果矩阵为正半定值(即它有一个或多个零特征值),则问题是一个凸QP,可以有效地解决。然而,许多解决者需要一个积极明确的目标。由于正半定QP的目标有一个非平凡的零空间,因此可能有许多解。事实上,解集甚至可以是*的。数值算法只会给出一个近似解,因此,矩阵的特征值完全为零是非常重要的。你可以通过在对角线上加一个带小正值的对角矩阵来确定矩阵的正定值。这将从本质上选择最小2规范的解决方案。在实践中,即使矩阵是正定的,这样做也是一个好主意,因为具有接近零的特征值的矩阵经常会导致数值求解的问题。要添加多少对角线,是稳定性和准确性之间的权衡。

If the matrix is indefinite (i.e. it has even one negative eigenvalue) then the problem is NP-hard. That means any codes based on currently available algorithms will have unreasonable worst-case running times even for moderate sized problems. If your problem has some special structure or you don't require a globally optimal solution then you might be ok. A typical approach is to look for a convex relaxation.

如果矩阵是不定的(即它有一个负的特征值),那么这个问题就是np困难。这意味着任何基于现有算法的代码,即使对于中等规模的问题,也会有不合理的最坏情况运行时间。如果你的问题有一些特殊的结构,或者你不需要一个全局最优的解决方案,那么你就可以了。典型的方法是寻找一个凸松弛。

#2


4  

LAPACK has a number of Cholesky decomposition routines (they call it Cholesky factorization). There are C++ wrappers available for LAPACK (see this SO question for a list).

LAPACK有一些Cholesky分解例程(他们称之为Cholesky分解)。有一些用于LAPACK的c++包装器(请参阅列表中的这个问题)。

The answer from Anycom in that post is a bit cryptic, but he meant that there are LAPACK bindings that can be used together with Boost's linear algebra library, uBLAS.

在这篇文章中,Anycom的答案有点神秘,但他的意思是,可以与Boost的线性代数库uBLAS一起使用LAPACK绑定。


I've found this library: OOQP (Object-Oriented Software for Quadratic Programming). If you scroll down that page, you'll find a research paper and a user guide. There seems to be a C++ API for that library. Hope this helps.

我发现了这个库:OOQP(用于二次编程的面向对象软件)。如果你向下滚动页面,你会发现一个研究报告和一个用户指南。这个库似乎有一个c++ API。希望这个有帮助。

#3


4  

CGAL looks great for quadratic programming. There is even a manual.

CGAL看起来很适合二次规划。甚至还有一本手册。

  // by default, we have a nonnegative QP with Ax <= b
  Program qp (CGAL::SMALLER, true, 0, false, 0); 

  // now set the non-default entries: 
  const int X = 0; 
  const int Y = 1;
  qp.set_a(X, 0,  1); qp.set_a(Y, 0, 1); qp.set_b(0, 7);  //  x + y  <= 7
  qp.set_a(X, 1, -1); qp.set_a(Y, 1, 2); qp.set_b(1, 4);  // -x + 2y <= 4
  qp.set_u(Y, true, 4);                                   //       y <= 4
  qp.set_d(X, X, 2); qp.set_d (Y, Y, 8); // !!specify 2D!!    x^2 + 4 y^2
  qp.set_c(Y, -32);                                       // -32y
  qp.set_c0(64);                                          // +64

  // solve the program, using ET as the exact type
  Solution s = CGAL::solve_quadratic_program(qp, ET());
  assert (s.solves_quadratic_program(qp));

Code from the first example.

第一个示例中的代码。

#4


2  

The subtlety that many of the answers above are missing is whether the matrix is only positive semi-definite (PSD) or is actually indefinite. I haven't used quadprog, but if it fails on a PSD objective matrix, that's a sign of the software's lack of robustness (convex QPs are often PSD, where only strictly convex QPs are positive definite). According to Golub's book "Matrix Computations", Cholesky factorization can be applied to PSD matrices, but numerical stability tends to suffer.

上面许多答案所忽略的微妙之处是,矩阵是否只是正半定(PSD),或者实际上是不确定的。我没有使用quadprog,但如果它在PSD目标矩阵上失败,这是软件缺乏鲁棒性的一个标志(凸QPs通常是PSD,只有严格的凸QPs是正定的)。根据Golub的书“矩阵计算”,Cholesky分解可以应用于PSD矩阵,但数值稳定性往往会受到影响。

For general nonlinear programming software- both convex and non-convex, the COIN-OR project maintains lists of free and non-free software. One of the solvers they list is IPOPT, which is certainly capable of solving your problem. IPOPT uses an interior-point algorithm, which for small problems, is generally slower than the active-set methods (like quadprog uses). As an alternative, you can formulate your QP as a linear complementarity problem (LCP) and then solve it using an LCP solver. I've found Fackler and Miranda's Matlab code LEMKE to be easily portable to C++.

对于一般的非线性规划软件——凸和非凸,COIN-OR项目维护*和非*软件的列表。他们列出的一个解决方案是IPOPT,它当然能够解决你的问题。IPOPT使用一个内部点算法,对于小问题,通常比主动设置方法(如quadprog使用)慢。作为一个备选方案,您可以将QP作为一个线性互补问题(LCP)来制定,然后使用LCP解决方案解决它。我找到了Fackler和Miranda的Matlab代码LEMKE,便于携带到c++。

#5


1  

If you are willing to pay, you can use Mosek. There is a free 30 day trial, though. It is generally considered the fastest solver available (no citation, sorry) The interface is C style, though obviously perfectally callalbe from C++. Mosek is really more of a conic programming solver, but if you don't feel like reformulating your problem as a conic problem (Mosek has a lot of documentation on how to do this), you can still use its stochastic gradient descent solver to solve your quadratic formulation.

如果你愿意支付,你可以使用Mosek。不过,还有30天的免费试用期。它通常被认为是最快的解决方案(没有引用,抱歉),接口是C风格,虽然很明显是来自c++的完美的callalbe。Mosek实际上更多的是一个圆锥编程的解决方案,但是如果您不想将您的问题重新定义为一个conic问题(Mosek有很多关于如何实现这个问题的文档),您仍然可以使用它的随机梯度下降求解器来解决您的二次公式。

#1


5  

There are several libraries that include QP solvers. There are both open-source and commercial options. The existing answers list a few of these. I'd like to clarify the issue with the matrix.

有几个库包括QP解决程序。有开源和商业选择。现有的答案列出了其中的一些。我想澄清一下这个矩阵的问题。

I assume you are referring to the objective matrix. The constraint matrix only needs to lead to a non-empty feasible set. You mentioned that the matrix is not suitable for Cholesky decomposition. Since the Cholesky decomposition can be formed for any positive definite matrix, the implication is that your matrix is not positive definite.

我假设你指的是客观矩阵。约束矩阵只需要引入一个非空的可行集合,你提到这个矩阵不适合乔列斯基分解。由于Cholesky分解可以形成任何正定矩阵,这意味着你的矩阵不是正定的。

If the matrix is positive semi-definite (i.e. it has one or more zero eigenvalues) then the problem is a convex QP and can be solved efficiently. However, many solvers require a positive definite objective. Since the objective of a positive semi-definite QP has a non-trivial nullspace, there may be many solutions. In fact, the set of solutions can even be unbounded. Numerical algorithms will only give an approximate solution anyways, so it is rarely important that the matrix have eigenvalues that are exactly zero. You can make the matrix positive definite by adding a diagonal matrix with a small positive value on the diagonal. This will essentially select the solution with the smallest 2-norm. In practice, it is a good idea to do this even when the matrix is positive definite because matrices that have eigenvalues close to zero can often cause problems with numerical solvers. How much diagonal to add in is a tradeoff between stability and accuracy.

如果矩阵为正半定值(即它有一个或多个零特征值),则问题是一个凸QP,可以有效地解决。然而,许多解决者需要一个积极明确的目标。由于正半定QP的目标有一个非平凡的零空间,因此可能有许多解。事实上,解集甚至可以是*的。数值算法只会给出一个近似解,因此,矩阵的特征值完全为零是非常重要的。你可以通过在对角线上加一个带小正值的对角矩阵来确定矩阵的正定值。这将从本质上选择最小2规范的解决方案。在实践中,即使矩阵是正定的,这样做也是一个好主意,因为具有接近零的特征值的矩阵经常会导致数值求解的问题。要添加多少对角线,是稳定性和准确性之间的权衡。

If the matrix is indefinite (i.e. it has even one negative eigenvalue) then the problem is NP-hard. That means any codes based on currently available algorithms will have unreasonable worst-case running times even for moderate sized problems. If your problem has some special structure or you don't require a globally optimal solution then you might be ok. A typical approach is to look for a convex relaxation.

如果矩阵是不定的(即它有一个负的特征值),那么这个问题就是np困难。这意味着任何基于现有算法的代码,即使对于中等规模的问题,也会有不合理的最坏情况运行时间。如果你的问题有一些特殊的结构,或者你不需要一个全局最优的解决方案,那么你就可以了。典型的方法是寻找一个凸松弛。

#2


4  

LAPACK has a number of Cholesky decomposition routines (they call it Cholesky factorization). There are C++ wrappers available for LAPACK (see this SO question for a list).

LAPACK有一些Cholesky分解例程(他们称之为Cholesky分解)。有一些用于LAPACK的c++包装器(请参阅列表中的这个问题)。

The answer from Anycom in that post is a bit cryptic, but he meant that there are LAPACK bindings that can be used together with Boost's linear algebra library, uBLAS.

在这篇文章中,Anycom的答案有点神秘,但他的意思是,可以与Boost的线性代数库uBLAS一起使用LAPACK绑定。


I've found this library: OOQP (Object-Oriented Software for Quadratic Programming). If you scroll down that page, you'll find a research paper and a user guide. There seems to be a C++ API for that library. Hope this helps.

我发现了这个库:OOQP(用于二次编程的面向对象软件)。如果你向下滚动页面,你会发现一个研究报告和一个用户指南。这个库似乎有一个c++ API。希望这个有帮助。

#3


4  

CGAL looks great for quadratic programming. There is even a manual.

CGAL看起来很适合二次规划。甚至还有一本手册。

  // by default, we have a nonnegative QP with Ax <= b
  Program qp (CGAL::SMALLER, true, 0, false, 0); 

  // now set the non-default entries: 
  const int X = 0; 
  const int Y = 1;
  qp.set_a(X, 0,  1); qp.set_a(Y, 0, 1); qp.set_b(0, 7);  //  x + y  <= 7
  qp.set_a(X, 1, -1); qp.set_a(Y, 1, 2); qp.set_b(1, 4);  // -x + 2y <= 4
  qp.set_u(Y, true, 4);                                   //       y <= 4
  qp.set_d(X, X, 2); qp.set_d (Y, Y, 8); // !!specify 2D!!    x^2 + 4 y^2
  qp.set_c(Y, -32);                                       // -32y
  qp.set_c0(64);                                          // +64

  // solve the program, using ET as the exact type
  Solution s = CGAL::solve_quadratic_program(qp, ET());
  assert (s.solves_quadratic_program(qp));

Code from the first example.

第一个示例中的代码。

#4


2  

The subtlety that many of the answers above are missing is whether the matrix is only positive semi-definite (PSD) or is actually indefinite. I haven't used quadprog, but if it fails on a PSD objective matrix, that's a sign of the software's lack of robustness (convex QPs are often PSD, where only strictly convex QPs are positive definite). According to Golub's book "Matrix Computations", Cholesky factorization can be applied to PSD matrices, but numerical stability tends to suffer.

上面许多答案所忽略的微妙之处是,矩阵是否只是正半定(PSD),或者实际上是不确定的。我没有使用quadprog,但如果它在PSD目标矩阵上失败,这是软件缺乏鲁棒性的一个标志(凸QPs通常是PSD,只有严格的凸QPs是正定的)。根据Golub的书“矩阵计算”,Cholesky分解可以应用于PSD矩阵,但数值稳定性往往会受到影响。

For general nonlinear programming software- both convex and non-convex, the COIN-OR project maintains lists of free and non-free software. One of the solvers they list is IPOPT, which is certainly capable of solving your problem. IPOPT uses an interior-point algorithm, which for small problems, is generally slower than the active-set methods (like quadprog uses). As an alternative, you can formulate your QP as a linear complementarity problem (LCP) and then solve it using an LCP solver. I've found Fackler and Miranda's Matlab code LEMKE to be easily portable to C++.

对于一般的非线性规划软件——凸和非凸,COIN-OR项目维护*和非*软件的列表。他们列出的一个解决方案是IPOPT,它当然能够解决你的问题。IPOPT使用一个内部点算法,对于小问题,通常比主动设置方法(如quadprog使用)慢。作为一个备选方案,您可以将QP作为一个线性互补问题(LCP)来制定,然后使用LCP解决方案解决它。我找到了Fackler和Miranda的Matlab代码LEMKE,便于携带到c++。

#5


1  

If you are willing to pay, you can use Mosek. There is a free 30 day trial, though. It is generally considered the fastest solver available (no citation, sorry) The interface is C style, though obviously perfectally callalbe from C++. Mosek is really more of a conic programming solver, but if you don't feel like reformulating your problem as a conic problem (Mosek has a lot of documentation on how to do this), you can still use its stochastic gradient descent solver to solve your quadratic formulation.

如果你愿意支付,你可以使用Mosek。不过,还有30天的免费试用期。它通常被认为是最快的解决方案(没有引用,抱歉),接口是C风格,虽然很明显是来自c++的完美的callalbe。Mosek实际上更多的是一个圆锥编程的解决方案,但是如果您不想将您的问题重新定义为一个conic问题(Mosek有很多关于如何实现这个问题的文档),您仍然可以使用它的随机梯度下降求解器来解决您的二次公式。