IPOPT 求解优化问题示例

16 篇文章 1 订阅

求解模型

状态变量 $ x = [x_1,x_2,x_3,x_4]^\mathrm{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 $

求解代码

example.cpp

#include <cppad/ipopt/solve.hpp>
#include <iostream>

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;
    // initial value of the independent variables
    Dvector xi(nx);
    xi[0] = 1.0;
    xi[1] = 1.0;
    xi[2] = 1.0;
    xi[3] = 1.0;
    // lower and upper limits for x
    Dvector xl(nx), xu(nx);
    for(i = 0; i < nx; i++)
    {     xl[i] = 1.0;
        xu[i] = 5.0;
    }
    // lower and upper limits for g
    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";

    Ipopt::SmartPtr<Ipopt::IpoptApplication> app = new Ipopt::IpoptApplication();

    // place to return solution
    CppAD::ipopt::solve_result<Dvector> solution;
    double cppad_time(0.0f), ipopt_time(0.0f);

    // solve the problem
    CppAD::ipopt::solve<Dvector, FG_eval>(app, options, xi, xl, xu, gl, gu, fg_eval, solution,cppad_time,ipopt_time);
    //
    // 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;
}

CMakeLists.txt

project(ipopt_example)
cmake_minimum_required(VERSION 2.8)

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)

编译求解结果:

$ mkdir build
$ cd build
$ cmake ..
$ make -j8
$ ./solver
1, 1
4.743, 4.743
3.82115, 3.82115
1.37941, 1.37941

参考: https://github.com/qianqian121/ipopt_example

  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
内点优化(interior point optimization)是一种常用的数学优化算法,它在求解非线性优化问题时非常有效。而IPOPT(Interior Point Optimization Toolkit)是一个广泛使用的开源内点优化软件包。Matlab是一种常用的数值计算与编程工具,可以用于调用IPOPT进行非线性优化求解。 使用Matlab调用IPOPT进行内点优化,一般需要进行以下几个步骤: 第一步是设置问题的约束条件和目标函数。在Matlab中,可以使用函数和符号表达式来表示目标函数和约束条件,并将它们转化为IPOPT所需要的格式。 第二步是选择合适的优化参数和初始点。在进行内点优化时,需要选择合适的参数来控制算法的收敛性和求解速度,并为每个变量指定一个初始点。 第三步是调用IPOPT求解问题。通过将设置好的目标函数、约束条件、初始点和优化参数传递给IPOPT的接口函数,可以调用IPOPT进行求解。 第四步是获取优化结果及其可行性和收敛性信息。求解完成后,可以通过检查求解状态和获取优化结果来判断问题的可行性和是否达到了收敛。 最后一步是根据需要进行后处理和分析。可以对优化结果进行进一步的处理和分析,以满足具体的需求。 总而言之,使用Matlab调用IPOPT进行内点优化需要进行一系列的设置和调用步骤,掌握这些步骤可以帮助我们高效地求解非线性优化问题
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值