• Ubuntu 20.04安装ipopt和cppAD(安装全流程+报错解决)


    参考资料

    在进行cppad和ipopt的安装时,发现在按照其他博主写的博客进行安装时总是会出现各种各样他们没遇到的问题,所以这里也记录下自己成功安装的步骤。

    1. Ipopt安装

    这边提供3种方式进行安装,可以先尝试使用方式1,方式1不行的话尝试方式2,方式2不行最后再尝试方式3.

    1. 方式1: 命令行安装

    sudo apt-get install coinor-libipopt
    
    • 1

    我这边使用命令行安装时显示无法定位软件包,在更新软件源后依旧无法生效,所以这个方式我放弃了。

    在这里插入图片描述

    2. 方式2:源码安装

    1. 安装依赖

      sudo apt-get install gcc g++ gfortran git patch wget pkg-config liblapack-dev libmetis-dev libblas-dev 
      
      • 1
    2. 创建一个存放所有跟Ipopt相关的文件夹,便于管理

      mkdir ~/Ipopt_pkg
      cd Ipopt_pkg
      
      • 1
      • 2
    3. 安装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 ..
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    4. 安装HSL

      git clone https://github.com/coin-or-tools/ThirdParty-HSL.git
      cd ThirdParty-HSL
      # 接下来需要下载coinhsl文件,并解压到ThirdParty-HSL目录下
      
      • 1
      • 2
      • 3

      下载coinhsl文件,并解压到ThirdParty-HSL目录下

      ThirdParty-HSL目录下,执行以下命令

      sudo ./configure
      sudo make
      sudo make install
      cd ..
      
      • 1
      • 2
      • 3
      • 4
    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 ..
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    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
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    7. 完善环境

      cd /usr/local/include
      sudo cp coin-or coin -r
      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
      
      • 1
      • 2
      • 3
      • 4
      • 5

    到这里都没有报错则安装完成。

    3. 方式3:源码安装

    1. 首先,安装依赖

      sudo apt-get install gfortran
      apt-get install unzip
      
      • 1
      • 2
    2. 下载Ipopt压缩包,并解压。

      wget https://www.coin-or.org/download/source/Ipopt/Ipopt-3.12.7.zip 
      unzip Ipopt-3.12.7.zip
      
      • 1
      • 2

      在使用wget方式下载Ipopt压缩包时,可能因为网络原因下载不了,那么可以直接进入网址,找到Ipopt-3.12.7.zip进行手动下载即可。
      在这里插入图片描述

    3. 下载并解压完成后,进入Ipopt-3.12.7文件夹,执行新建文件 install_ipopt.sh

      touch install_ipopt.sh
      
      • 1
    4. 打开该文件,并写入以下内容:

      # Pass the Ipopt source directory as the first argument
      if [ -z $1 ]
      then
          echo "Specifiy the location of the Ipopt source directory in the first argument."
          exit
      fi
      cd $1
      
      prefix=/usr/local
      srcdir=$PWD
      
      echo "Building Ipopt from ${srcdir}"
      echo "Saving headers and libraries to ${prefix}"
      
      # BLAS
      cd $srcdir/ThirdParty/Blas
      ./get.Blas
      mkdir -p build && cd build
      ../configure --prefix=$prefix --disable-shared --with-pic
      make install
      
      # Lapack
      cd $srcdir/ThirdParty/Lapack
      ./get.Lapack
      mkdir -p build && cd build
      ../configure --prefix=$prefix --disable-shared --with-pic \
          --with-blas="$prefix/lib/libcoinblas.a -lgfortran"
      make install
      
      # ASL
      cd $srcdir/ThirdParty/ASL
      ./get.ASL
      
      # MUMPS
      cd $srcdir/ThirdParty/Mumps
      ./get.Mumps
      
      # build everything
      cd $srcdir
      ./configure --prefix=$prefix coin_skip_warn_cxxflags=yes \
          --with-blas="$prefix/lib/libcoinblas.a -lgfortran" \
          --with-lapack=$prefix/lib/libcoinlapack.a
      make
      make test
      make -j1 install
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
    5. 给该文件添加可执行权限:

      sudo chmod +x install_ipopt.sh
      
      • 1
    6. 然后运行脚本:

      ./install_ipopt.sh Ipopt-3.12.7
      
      • 1

      运行脚本后,有可能因为网络问题运行失败,可以多尝试几次。
      在这里插入图片描述

    最后静静等待安装即可。

    最终,我是使用方式2步骤进行安装的。方式3因为网络问题,比较难成功。

    4. Ipopt测试

    进入 IPOPT 源码文件夹如下位置,用官方例子测试

    cd Ipopt/build/examples/Cpp_example
    sudo make
    ./cpp_example
    
    • 1
    • 2
    • 3

    出现以下界面说明安装成功

    在这里插入图片描述

    5. 报错修复

    安装完成后,有可能后期在使用阶段会编译报错:
    在这里插入图片描述

    /usr/include/coin/IpSmartPtr.hpp:19:4: error: #error "don't have header file for stddef"
    
    • 1

    需要通过以下方式解决。

    打开文件

    sudo gedit /usr/include/coin/IpSmartPtr.hpp
    
    • 1

    在文件的预处理部分,添加如下内容

    #define HAVE_CSTDDEF // 添加部分
    #ifdef HAVE_CSTDDEF
    # include 
    #else
    # ifdef HAVE_STDDEF_H
    #  include 
    # else
    #  error "don't have header file for stddef"
    # endif
    #endif
    #undef HAVE_CSTDDEF // 添加部分
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    2. CppAD安装

    先尝试方式1,方式1不行再尝试方式2。

    1. 方式1:命令行安装

    一般网上已有的教程都是说直接在终端中输入以下命令安装:

    sudo apt-get install cppad
    
    • 1

    但是,使用这种方式可能找不到该库。
    在这里插入图片描述

    遇到这个问题时,可以尝试切换源。切换源方式见博客。切换源后再进行更新。

    sudo apt update
    
    • 1

    然后再重新尝试安装。

    安装完成后如果需要卸载,则执行以下命令:

    sudo apt-get remove cppad
    
    • 1

    如果上述方式无法成功安装,可采取下面源码的方式安装。

    2. 方式2:源码方式安装

    使用源码的方式安装。

    1. 下载源码:

      git clone https://github.com/coin-or/CppAD.git 
      
      • 1
    2. 下载完成后,进入CppAD文件夹,然后执行以下命令:

      mkdir build
      cd build
      cmake ..
      make 
      sudo make install
      
      • 1
      • 2
      • 3
      • 4
      • 5

      即可安装成功。

    3. 如果需要卸载的话,在CppAD/build文件夹内执行以下命令即可:

      	sudo make uninstall
      
      • 1

    3. CppAD测试

    使用以下代码测试CppAD是否安装成功。

    • CppAD_demo.cpp文件

      # include         // standard input/output
      # include           // standard vector
      # include  // the CppAD package
      
      namespace { // begin the empty namespace
          // define the function Poly(a, x) = a[0] + a[1]*x[1] + ... + a[k-1]*x[k-1]
          template <class Type>
          Type Poly(const CPPAD_TESTVECTOR(double) &a, const Type &x)
          {   size_t k  = a.size();
              Type y   = 0.;  // initialize summation
              Type x_i = 1.;  // initialize x^i
              for(size_t i = 0; i < k; i++)
              {   y   += a[i] * x_i;  // y   = y + a_i * x^i
                  x_i *= x;           // x_i = x_i * x
              }
              return y;
          }
      }
      // main program
      int main(void)
      {   using CppAD::AD;   // use AD as abbreviation for CppAD::AD
          using std::vector; // use vector as abbreviation for std::vector
      
          // vector of polynomial coefficients
          size_t k = 5;                  // number of polynomial coefficients
          CPPAD_TESTVECTOR(double) a(k); // vector of polynomial coefficients
          for(size_t i = 0; i < k; i++)
              a[i] = 1.;                 // value of polynomial coefficients
      
          // domain space vector
          size_t n = 1;               // number of domain space variables
          vector< AD<double> > ax(n); // vector of domain space variables
          ax[0] = 3.;                 // value at which function is recorded
      
          // declare independent variables and start recording operation sequence
          CppAD::Independent(ax);
      
          // range space vector
          size_t m = 1;               // number of ranges space variables
          vector< AD<double> > ay(m); // vector of ranges space variables
          ay[0] = Poly(a, ax[0]);     // record operations that compute ay[0]
      
          // store operation sequence in f: X -> Y and stop recording
          CppAD::ADFun<double> f(ax, ay);
      
          // compute derivative using operation sequence stored in f
          vector<double> jac(m * n); // Jacobian of f (m by n matrix)
          vector<double> x(n);       // domain space vector
          x[0] = 3.;                 // argument value for computing derivative
          jac  = f.Jacobian(x);      // Jacobian for operation sequence
      
          // print the results
          std::cout << "f'(3) computed by CppAD = " << jac[0] << std::endl;
      
          // check if the derivative is correct
          int error_code;
          if( jac[0] == 142. )
              error_code = 0;      // return code for correct case
          else  error_code = 1;    // return code for incorrect case
      
          return error_code;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
    • CMakeLists.txt文件

      cmake_minimum_required(VERSION 3.21)
      
      project(testCPP)
      
      set(CMAKE_CXX_STANDARD 14)
      
      add_executable(CppAD_demo CppAD_demo.cpp)
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    • 在该项目目录内执行

      mkdir build
      cd build
      cmake ../
      make
      ./CppAD_demo
      
      • 1
      • 2
      • 3
      • 4
      • 5

      输出以下信息,则CppAD安装成功
      在这里插入图片描述

    3. 测试Ipopt与CppAD是否可用

    以下例子来自于博客

    1. 例子

    利用CppAD与Ipopt求解以下非线性规划问题

    minimize ⁡ x 1 x 4 ( x 1 + x 2 + x 3 ) + x 3  s.t.  x 1 x 2 x 3 x 4 ≥ 25 x 1 2 + x 2 2 + x 3 2 + x 4 2 = 40 1 ≤ x 1 , x 2 , x 3 , x 4 ≤ 5

    minimizex1x4(x1+x2+x3)+x3 s.t. x1x2x3x425x12+x22+x32+x42=401x1,x2,x3,x45" role="presentation">minimizex1x4(x1+x2+x3)+x3 s.t. x1x2x3x425x12+x22+x32+x42=401x1,x2,x3,x45
    minimize s.t. x1x4(x1+x2+x3)+x3x1x2x3x425x12+x22+x32+x42=401x1,x2,x3,x45

    • cppad_ipopt_demo.cpp文件

      #include 
      #include 
      
      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;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
      • 79
      • 80
      • 81
      • 82
      • 83
      • 84
      • 85
      • 86
      • 87
      • 88
      • 89
      • 90
      • 91
      • 92
      • 93
      • 94
      • 95
      • 96
      • 97
      • 98
      • 99
      • 100
      • 101
      • 102
      • 103
      • 104
      • 105
      • 106
      • 107
      • 108
      • 109
      • 110
    • CMakeLists.txt文件

      cmake_minimum_required(VERSION 3.21)
      project(testCPP)
      
      set(CMAKE_CXX_STANDARD 14)
      
      add_executable(cppad_ipopt_demo cppad_ipopt_demo.cpp)
      target_link_libraries(cppad_ipopt_demo ipopt)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    • 在该项目目录内执行

      mkdir build
      cd build
      cmake ../
      make
      ./cppad_ipopt_demo
      
      • 1
      • 2
      • 3
      • 4
      • 5

      若输出如下信息,则说明Ipopt与CppAD安装成功。

      在这里插入图片描述

    2. 编译报错解决

    1. Undefined reference to `Ipopt::IpoptApplication::IpoptApplication(bool, bool)’

    这里需要注意的是,CMakeLists.txt文件需要加入target_link_libraries(cppad_ipopt_demo ipopt)链接,否则会报如下错误:

    Undefined reference to `Ipopt::IpoptApplication::IpoptApplication(bool, bool)'
    
    • 1

    在这里插入图片描述

    2. fatal error: coin/IpIpoptApplication.hpp: No such file or directorycompilation terminated.

    若编译后报错:

    fatal error: coin/IpIpoptApplication.hpp: No such file or directorycompilation terminated.
    
    • 1

    这是由缺少coin_or库引起的,可以执行以下命令安装

    sudo apt install coinor-libipopt-dev
    
    • 1

    以上所有代码存于github仓库

  • 相关阅读:
    你可能需要的vue相关考点汇总
    selenium——chromdriver版本请及时更新
    线下门店如何根据员工排班情况给客户预约
    Java 线程池调度周期性任务“异常“探究
    c#学习系列相关之多线程(三)----invoke和begininvoke
    2022年 6 月面试题 100 + 大全(合适各级 Java 人员)
    MSE = Bias² + Variance?什么是“好的”统计估计器
    Android上面做Flash播放器
    git中rebase和merge的区别
    jsp公交查询系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
  • 原文地址:https://blog.csdn.net/weixin_42301220/article/details/127946528