根据官网例程实现非线性规划问题求解。
文件demo.cpp代码。
#include <vector>
#include <math.h>
#include <cppad/cppad.hpp>
#include <cppad/ipopt/solve.hpp>
#include "Eigen-3.3/Eigen/Core"
#include "Eigen-3.3/Eigen/QR"
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);
//var
AD<double> x1=x[0];
AD<double> x2=x[1];
AD<double> x3=x[2];
AD<double> x4=x[3];
//cost function f(x)
fg[0]=x1*x4*(x1+x2+x3)+x3;
//constraints function
fg[1]=x1*x2*x3*x4;
fg[2]=x1*x1+x2*x2+x3*x3+x4*x4;
return;
}
};
int main() {
bool ok=true;
size_t i;
typedef CPPAD_TESTVECTOR(double) Dvector;
// number of independent vars
size_t nx=4;
// number of constraints
size_t ng=2;
// initial value of the independent vars
Dvector xi(nx);
xi[0]=1.0;
xi[1]=5.0;
xi[2]=5.0;
xi[3]=1.0;
//lower and upper limits for var
Dvector xl(nx), xu(nx);
for(i=0;i<nx;i++){
xl[i]=1.0;
xu[i]=5.0;
}
//lower and upper limits for constraints
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 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 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";
/*
std::string options;
options += "Integer print_level 0\n";
options += "Sparse true forward\n";
options += "Sparse true reverse\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
std::vector<double> array;
for(i = 0; i < nx; i++)
{ ok &= CppAD::NearEqual(
check_x[i], solution.x[i], rel_tol, abs_tol
// array[i]=solution.x[i];
);
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
);
}
std::cout << ok << std::endl;
std::cout << solution.x[0] << std::endl;
std::cout << solution.x[1] << std::endl;
std::cout << solution.x[2] << std::endl;
std::cout << solution.x[3] << std::endl;
std::cout << solution.zl[0] << std::endl;
}
说明:变量初始值/变量下限/变量上限/约束下限/约束上限/目标函数+等式不等式约束/
类FG_eval 组织方程;主程序中组织变量/上限/下限/求解参数等
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);
//var
AD<double> x1=x[0];
AD<double> x2=x[1];
AD<double> x3=x[2];
AD<double> x4=x[3];
//cost function f(x)
fg[0]=x1*x4*(x1+x2+x3)+x3;
//constraints function
fg[1]=x1*x2*x3*x4;
fg[2]=x1*x1+x2*x2+x3*x3+x4*x4;
return;
}
};