Ipopt 和cppAD是用于求解二次规划问题等的C++库,其安装成败对科研、工作相当重要,故贴次流程。本教程参照官方教程,这里不贴链接,因为你不需要,这个教程足够你成功配置。
一、 Ipopt 安装
(注意:后面有直接命令安装ipopt的教程。。。经过测试使用该源码安装方法安装的ipopt在使用一段时间后可能出现报错无法求解情况。。。求稳建议直接采用命令安装(二、命令行安装))
1. 安装依赖
sudo apt-get install gcc g++ gfortran git patch wget pkg-config liblapack-dev libmetis-dev
2. 创建一个专属目录方便管理
mkdir ~/Ipopt_pkg
cd Ipopt_pkg
2. 安装ASL
git clone https://github.com/coin-or-tools/ThirdParty-ASL.git
cd ThirdParty-ASL
sudo ./get.ASL
sudo ./configure
sudo make
sudo make install
cd ..
3. 安装.BLAS 和LAPACK
sudo apt-get install libblas-dev
sudo apt-get install liblapack-dev
4. 安装HSL
这个安装需要两个步骤,注意!第一步你可能要多动动小手。
a. 下载coinhsl文件(这个文件可以在其他地方下,不过我不建议,因为懒得找)
链接:https://pan.baidu.com/s/1BfGxoH-ReSBS1dphB9n-tQ
提取码:oc8a
b. 安装
git clone https://github.com/coin-or-tools/ThirdParty-HSL.git
cd ThirdParty-HSL
#注意这里要把步骤a.的文件coinhsl解压拷贝到ThirdParty-HSL目录下再执行下面的命令
sudo ./configure
sudo make
sudo make install
cd ..
5. 安装MUMPS
git clone https://github.com/coin-or-tools/ThirdParty-Mumps.git
cd ThirdParty-Mumps
sudo ./get.Mumps
sudo ./configure
sudo make
sudo make install
cd ..
6. 安装Ipopt
git clone https://github.com/coin-or/Ipopt.git
cd Ipopt
mkdir build
cd build
sudo ../configure
sudo make
sudo make test
sudo make install
7. 完善环境1.0
cd /usr/local/include
sudo cp coin-or coin -r
8. 完善环境2.0
sudo ln -s /usr/local/lib/libcoinmumps.so.3 /usr/lib/libcoinmumps.so.3
sudo ln -s /usr/local/lib/libcoinhsl.so.2 /usr/lib/libcoinhsl.so.2
sudo ln -s /usr/local/lib/libipopt.so.3 /usr/lib/libipopt.so.3
完成安装
二、命令行直接安装IPOPT
sudo apt-get install coinor-libipopt-dev
安装完成后编译工程会报一个错误,可以通过如下操作修复:
sudo vim /usr/include/coin/IpSmartPtr.hpp
修改文件的预处理部分,如下内容(注释为修改部分的两条语句):
#define HAVE_CSTDDEF // 修改部分
#ifdef HAVE_CSTDDEF
# include <cstddef>
#else
# ifdef HAVE_STDDEF_H
# include <stddef.h>
# else
# error "don't have header file for stddef"
# endif
#endif
#undef HAVE_CSTDDEF // 修改部分
完成安装(实测该方法比源码稳定,也方便)
三、 cppAD 安装
sudo apt-get install cppad
找个例程跑跑:cppad_ipopt_demo.cpp
#include <iostream>
#include <cppad/ipopt/solve.hpp>
using namespace std;
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);
// variables
AD<double> x1 = x[0];
AD<double> x2 = x[1];
AD<double> x3 = x[2];
AD<double> x4 = x[3];
// f(x) objective function
fg[0] = x1 * x4 * (x1 + x2 + x3) + x3;
// constraints
fg[1] = x1 * x2 * x3 * x4;
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;
size_t nx = 4; // number of varibles
size_t ng = 2; // number of constraints
Dvector x0(nx); // initial condition of varibles
x0[0] = 1.0;
x0[1] = 5.0;
x0[2] = 5.0;
x0[3] = 1.0;
// lower and upper bounds for varibles
Dvector xl(nx), xu(nx);
for(i = 0; i < nx; i++)
{
xl[i] = 1.0;
xu[i] = 5.0;
}
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
string options;
// turn off any printing
options += "Integer print_level 0\n";
options += "String sb yes\n";
// maximum iterations
options += "Integer max_iter 10\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 tesing
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";
CppAD::ipopt::solve_result<Dvector> solution; // solution
CppAD::ipopt::solve<Dvector, FG_eval>(options, x0, xl, xu, gl, gu, fg_eval, solution); // solve the problem
cout<<"solution: "<<solution.x<<endl;
//
//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);
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()
{
cout << "CppAD : Hello World Demo!" << endl;
get_started();
return 0;
}
找个例程跑跑:.CMakeLists.txt
cmake_minimum_required(VERSION 2.8.3)
project(cppad_ipopt_demo)
set(CMAKE_CXX_STANDARD 14)
add_executable(cppad_ipopt_demo
cppad_ipopt_demo.cpp
)
target_link_libraries(cppad_ipopt_demo
m
ipopt
)
好了,你已经配置完了,去工作吧