6

Ipopt的使用

 2 years ago
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.
neoserver,ios ssh client

Ipopt的使用 | 沉默杀手

Ipopt的使用
2022-08-02|SLAM工具|
Word count: 729|Reading time: 4 min

IPOPT是一种常用的非线性优化求解器,使用内点法进行求解。对于复杂问题,需要借助自动微分工具,帮助求解梯度、雅各比矩阵、Hessian矩阵,如ADOL-C,CppAD

参考非线性优化求解器IPOPTubuntu 环境下 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 $

1≤x1,x2,x3,x4≤51≤x1,x2,x3,x4≤5

起始点 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;
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK