Ipopt的使用
source link: https://charon-cheung.github.io/2022/08/02/SLAM%E5%B7%A5%E5%85%B7/Ipopt%E7%9A%84%E4%BD%BF%E7%94%A8/#%E4%B8%BE%E4%BE%8B
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Ipopt的使用 | 沉默杀手
IPOPT是一种常用的非线性优化求解器,使用内点法进行求解。对于复杂问题,需要借助自动微分工具,帮助求解梯度、雅各比矩阵、Hessian矩阵,如ADOL-C,CppAD
参考非线性优化求解器IPOPT 和 ubuntu 环境下 IPOPT 安装与使用
CMake配置
message(status "IPOPT_CFLAGS: " ${IPOPT_CFLAGS})
message(status "IPOPT_CFLAGS_OTHER: " ${IPOPT_CFLAGS_OTHER})
set(CMAKE_CXX_FLAGS "-DHAVE_CSTDDEF -DHAVE_MPI_INITIALIZED")
include_directories(/usr/local/include)
link_directories(/usr/local/lib)
add_executable(solver example.cpp)
target_link_libraries(solver ipopt)
状态变量 x=[x1,x2,x3,x4]Tx=[x1,x2,x3,x4]T
目标函数 $ f(x) = x_1 x_4 (x_1 + x_2+ x_3) + x_3$
约束条件:
$ g_1(x) = x_1 x_2 x_3 * x_4 \ge 25 ;; g_2(x) = x^2_1 + x^2_2 + x^2_3 + x^2_4 = 40 $
起始点 x0=(1,5,5,1)x0=(1,5,5,1)
优化结果:x∗=(1.00000000,4.74299963,3.82114998,1.37940829)x∗=(1.00000000,4.74299963,3.82114998,1.37940829)
#include <cppad/ipopt/solve.hpp>
#include <iostream>
//#include <mpi.h>
namespace
{
using CppAD::AD;
class FG_eval {
public:
typedef CPPAD_TESTVECTOR( AD<double> ) ADvector;
void operator()(ADvector& fg, const ADvector& x)
{ assert( fg.size() == 3 );
assert( x.size() == 4 );
// Fortran style indexing
AD<double> x1 = x[0];
AD<double> x2 = x[1];
AD<double> x3 = x[2];
AD<double> x4 = x[3];
// f(x)
fg[0] = x1 * x4 * (x1 + x2 + x3) + x3;
// g_1 (x)
fg[1] = x1 * x2 * x3 * x4;
// g_2 (x)
fg[2] = x1 * x1 + x2 * x2 + x3 * x3 + x4 * x4;
return;
}
};
}
bool get_started(void)
{
bool ok = true;
size_t i;
typedef CPPAD_TESTVECTOR( double ) Dvector;
// number of independent variables (domain dimension for f and g)
size_t nx = 4;
// number of constraints (range dimension for g)
size_t ng = 2;
// x[i] 设置第i个变量的初始迭代值
Dvector xi(nx);
xi[0] = 1.0;
xi[1] = 1.0;
xi[2] = 1.0;
xi[3] = 1.0;
// x_l[i]设置xi的下界值, x_u[i]设置xi的上界值
Dvector xl(nx), xu(nx);
for(i = 0; i < nx; i++)
{
xl[i] = 1.0;
xu[i] = 5.0;
}
// g_l[i]设置约束i的下界值, g_u[i]设置约束i的上界值
Dvector gl(ng), gu(ng);
gl[0] = 25.0; gu[0] = 1.0e19;
gl[1] = 40.0; gu[1] = 40.0;
// object that computes objective and constraints
FG_eval fg_eval;
// options
std::string options;
// turn off any printing
options += "Integer print_level 0\n";
options += "String sb yes\n";
// maximum number of iterations
options += "Integer max_iter 100\n";
// approximate accuracy in first order necessary conditions;
// see Mathematical Programming, Volume 106, Number 1,
// Pages 25-57, Equation (6)
options += "Numeric tol 1e-6\n";
// derivative testing
options += "String derivative_test second-order\n";
// maximum amount of random pertubation; e.g.,
// when evaluation finite diff
options += "Numeric point_perturbation_radius 0.\n";
// place to return solution
CppAD::ipopt::solve_result<Dvector> solution;
// solve the problem
CppAD::ipopt::solve<Dvector, FG_eval>(
options, xi, xl, xu, gl, gu, fg_eval, solution
);
// Check some of the solution values
ok &= solution.status == CppAD::ipopt::solve_result<Dvector>::success;
double check_x[] = { 1.000000, 4.743000, 3.82115, 1.379408 };
double check_zl[] = { 1.087871, 0., 0., 0. };
double check_zu[] = { 0., 0., 0., 0. };
double rel_tol = 1e-6; // relative tolerance
double abs_tol = 1e-6; // absolute tolerance
for(i = 0; i < nx; i++)
{
ok &= CppAD::NearEqual(
check_x[i], solution.x[i], rel_tol, abs_tol );
std::cout << check_x[i] << ", " << solution.x[i] << std::endl;
ok &= CppAD::NearEqual(
check_zl[i], solution.zl[i], rel_tol, abs_tol );
ok &= CppAD::NearEqual(
check_zu[i], solution.zu[i], rel_tol, abs_tol );
}
return ok;
}
int main(int argc, const char** argv) {
//MPI_Init();
get_started();
return 0;
}
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK