esa / pagmo2

A C++ platform to perform parallel computations of optimisation tasks (global and local) via the asynchronous generalized island model.
https://esa.github.io/pagmo2/
GNU General Public License v3.0
804 stars 159 forks source link

How to optimize with algorithms::ipopt? #551

Closed castrovictor closed 11 months ago

castrovictor commented 1 year ago

I have followed the tutorials to define a simple problem. In my case, I want to optimize a simple quadratic funciton. I have been able to optimize it with the algorithm bee_colony(), but my goal is to use algorithms::ipopt. What I have done is passing it to the algorithm constructor. It does not throw any error, but the result is not correct, and it performs very few iterations.

Here it is what I am doing:

#include <string>
#include <pagmo/io.hpp>
#include <pagmo/problem.hpp>
#include <pagmo/types.hpp>
// Headers envolve a population
#include <pagmo/algorithms/ipopt.hpp>
#include <pagmo/population.hpp>
#include <iostream>

using namespace pagmo;

struct problem_basic {
    // Mandatory, computes ... well ... the fitness
    vector_double fitness(const vector_double &x) const
    {
        return { (+1)*(x[0]-1)*(x[0]-1)+3};
    }

    // Mandatory, returns the box-bounds
    std::pair<vector_double, vector_double> get_bounds() const
    {
        return {{-4}, {4}};
    }

     // Optional, computes the gradients. 

    vector_double gradient(const vector_double &x) const
    {
        return {2 * x[0]-2};
        //return {};

    }

    // Optional, provides a name for the problem overriding the default name
    std::string get_name() const
    {
        return "Basic optimization problem to test Pagmo";
    }

    // Optional, provides extra information that will be appended after
    // the default stream operator
    std::string get_extra_info() const
    {
        return "This is a simple toy problem to optimize a quadratic function";
    }

    // Optional methods-data can also be accessed later via
    // the problem::extract() method
    vector_double best_known() const
    {
        return {0.0};
    }
};

int main()
{
    // Initiate the basic problem
    problem p0{problem_basic{}};

    // Streaming to screen the problem
    std::cout << p0 << '\n';

    // 2 - Instantiate a pagmo algorithm
    std::cout << "Instantiate a pagmo algorithm..." << std::endl;
    algorithm algo{ipopt()};

    // 3 - Instantiate a population
    population pop{p0}; 

    std::cout << "Initial population is: " << std::endl;
    std::cout << "---------------------------------------" << std::endl;
    std::cout << pop << std::endl;
    std::cout << "---------------------------------------" << std::endl;

    // 4 - Evolve the population
    pop = algo.evolve(pop);

    // 5 - Output the population
    std::cout << "Final population is : \n" << pop;

}

The final output is the following, while it should be x=1 with fitness=3

List of individuals: 
#0:
        ID:                     5489344943891468856
        Decision vector:        [0]
        Fitness vector:         [4]

Champion decision vector: [0]
Champion fitness: [4]

Any help is aprecciated. Thank you.

castrovictor commented 1 year ago

Update: installed ipopt from apt. Now it starts optimizing but the computation never ends. Actually, it looks like the fitness function is never called. It seems more like ipopt problem itself, but still would need some help because I can not figure this out

castrovictor commented 11 months ago

Nevermind, I finally figured it out. It was some problems with the installation