![cover](https://img-home.csdnimg.cn/images/20230308044235.png)
C++中求解二次规划问题(OSQP)的一个使用实例
库的安装(eigen/OSQP/OSQP-eigen)及其他实例可以参考这个链接。,其中常数项对二次型求解没有影响,可以直接忽略。由于二次规划问题求解器默认的求解形式为。以下面的一个优化问题求解为例。Cmakelist文件如下。
C++中求解二次规划问题(OSQP)的一个使用实例
参考
库的安装(eigen/OSQP/OSQP-eigen)及其他实例可以参考这个链接
https://blog.csdn.net/nudt_zrs/article/details/124258999?spm=1001.2014.3001.5501
实例
以下面的一个优化问题求解为例
m
i
n
(
x
1
−
1
)
2
+
(
x
2
−
1
)
2
s
.
t
.
0
≤
x
1
≤
1.5
0
≤
x
2
≤
1.5
\begin{equation} \begin{split} &min \hspace{0.5cm}(x_1 - 1)^2 + (x_2 -1)^2 \\ &s.t.\hspace{1cm} 0 \leq x_1 \leq 1.5 \\ &\hspace{1.5cm} 0 \leq x_2 \leq 1.5 \end{split} \end{equation}
min(x1−1)2+(x2−1)2s.t.0≤x1≤1.50≤x2≤1.5
首先对目标方程进行简化,写成矩阵的形式:
o
b
j
=
(
x
1
2
−
2
x
1
+
1
)
+
(
x
2
2
−
2
x
2
+
1
)
=
x
1
2
+
x
2
2
−
2
x
1
−
2
x
2
+
2
=
[
x
1
x
2
]
[
1
0
0
1
]
[
x
1
x
2
]
−
2
[
1
1
]
[
x
1
x
2
]
+
2
\begin{equation} \begin{split} obj &= (x_1^2 - 2x_1 + 1) + (x_2^2-2x_2+1) \\ &= x_1^2 + x_2^2 -2x_1 - 2x_2 + 2 \\ &= \begin{bmatrix} x_1 & x_2 \end{bmatrix} \begin{bmatrix} 1 & 0 \\0 & 1 \end{bmatrix} \begin{bmatrix} x_1 \\ x_2 \end{bmatrix}- 2\begin{bmatrix} 1 & 1 \end{bmatrix} \begin{bmatrix} x_1 \\ x_2 \end{bmatrix}+ 2 \end{split} \end{equation}
obj=(x12−2x1+1)+(x22−2x2+1)=x12+x22−2x1−2x2+2=[x1x2][1001][x1x2]−2[11][x1x2]+2
由于二次规划问题求解器默认的求解形式为
o
b
j
=
1
2
x
T
H
x
+
f
T
x
obj=\displaystyle \frac 12x^THx + f^Tx
obj=21xTHx+fTx,其中常数项对二次型求解没有影响,可以直接忽略。因此将上式写为
o
b
j
=
1
2
x
T
[
2
0
0
2
]
x
+
[
−
2
−
2
]
T
x
=
1
2
x
T
H
x
+
f
T
x
\begin{equation} \begin{split} obj &= \frac 12\pmb x^T \begin{bmatrix} 2 & 0 \\0 & 2 \end{bmatrix} \pmb x + \begin{bmatrix} -2 \\ -2 \end{bmatrix}^T \pmb x \\ &= \frac 12 x^THx + f^Tx \end{split} \end{equation}
obj=21xT[2002]x+[−2−2]Tx=21xTHx+fTx
而其不等式约束则可改写为如下形式
[
0
0
]
≤
[
1
0
0
1
]
[
x
1
x
2
]
≤
[
1.5
1.5
]
⇒
l
b
≤
A
x
≤
u
b
\begin{equation} \begin{split} \begin{bmatrix} 0 \\ 0 \end{bmatrix} \leq &\begin{bmatrix} 1 & 0 \\ 0 &1 \end{bmatrix}\begin{bmatrix} x_1 \\ x_2 \end{bmatrix} \leq \begin{bmatrix} 1.5 \\ 1.5 \end{bmatrix} \\ \Rightarrow &lb \leq A x \leq ub \end{split} \end{equation}
[00]≤⇒[1001][x1x2]≤[1.51.5]lb≤Ax≤ub
// osqp-eigen
#include "OsqpEigen/OsqpEigen.h"
// eigen
#include <Eigen/Dense>
#include <iostream>
int main()
{
// allocate QP problem matrices and vectores
Eigen::SparseMatrix<double> hessian(2, 2); //P: n*n正定矩阵,必须为稀疏矩阵SparseMatrix
Eigen::VectorXd gradient(2); //Q: n*1向量
Eigen::SparseMatrix<double> linearMatrix(2, 2); //A: m*n矩阵,必须为稀疏矩阵SparseMatrix
Eigen::VectorXd lowerBound(2); //L: m*1下限向量
Eigen::VectorXd upperBound(2); //U: m*1上限向量
hessian.insert(0, 0) = 2.0; //注意稀疏矩阵的初始化方式,无法使用<<初始化
hessian.insert(1, 1) = 2.0;
// std::cout << "hessian:" << std::endl
// << hessian << std::endl;
gradient << -2, -2;
linearMatrix.insert(0, 0) = 1.0; //注意稀疏矩阵的初始化方式,无法使用<<初始化
linearMatrix.insert(1, 1) = 1.0;
// std::cout << "linearMatrix:" << std::endl
// << linearMatrix << std::endl;
lowerBound << 1, 1;
upperBound << 1.5, 1.5;
// instantiate the solver
OsqpEigen::Solver solver;
// settings
solver.settings()->setVerbosity(false);
solver.settings()->setWarmStart(true);
// set the initial data of the QP solver
solver.data()->setNumberOfVariables(2); //变量数n
solver.data()->setNumberOfConstraints(2); //约束数m
if (!solver.data()->setHessianMatrix(hessian))
return 1;
if (!solver.data()->setGradient(gradient))
return 1;
if (!solver.data()->setLinearConstraintsMatrix(linearMatrix))
return 1;
if (!solver.data()->setLowerBound(lowerBound))
return 1;
if (!solver.data()->setUpperBound(upperBound))
return 1;
// instantiate the solver
if (!solver.initSolver())
return 1;
Eigen::VectorXd QPSolution;
// solve the QP problem
if (!solver.solve())
{
return 1;
}
QPSolution = solver.getSolution();
std::cout << "QPSolution" << std::endl
<< QPSolution << std::endl; //输出为m*1的向量
return 0;
}
Cmakelist文件如下
cmake_minimum_required(VERSION 3.1)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project(OSQP_test LANGUAGES CXX)
find_package(OsqpEigen)
find_package(Eigen3)
include_directories(SYSTEM ${EIGEN3_INCLUDE_DIR})
#MPCExample
add_executable(OSQP_test main.cpp)
target_link_libraries(OSQP_test OsqpEigen::OsqpEigen)
![Logo](https://devpress.csdnimg.cn/79de2bf0b7994defa4242ef90d5513fa.jpg)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)