gp_parego.hpp 3.86 KB
Newer Older
Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef LIMBO_MODEL_GP_PAREGO_HPP
#define LIMBO_MODEL_GP_PAREGO_HPP

#include <iostream>
#include <cassert>
#include <limits>
#include <vector>

#include <Eigen/Core>
#include <Eigen/LU>
#include <Eigen/Cholesky>

#include <limbo/model/gp/no_lf_opt.hpp>

namespace limbo {
    namespace experimental {
17
18
19
20
21
22
        namespace defaults {
            struct model_gp_parego {
                BO_PARAM(double, rho, 0.05);
            };
        }
        namespace model {
Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
23

Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
24
25
26
27
28
29
30
31
32
            /// this is the model used in Parego
            /// reference: Knowles, J. (2006). ParEGO: A hybrid algorithm
            /// with on-line landscape approximation for expensive multiobjective
            /// optimization problems.
            /// IEEE Transactions On Evolutionary Computation, 10(1), 50-66.
            /// Main idea:
            /// - this models aggregates all the objective values with the Tchebycheff distance
            /// - objectives are weighted using a random vector
            /// - a single model is built
Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
33
34
35
36
37
38
            template <typename Params, typename Model>
            class GPParego : public Model {
            public:
                GPParego() {}
                GPParego(int dim_in, int dim_out) : Model(dim_in, 1), _nb_objs(dim_out) {}
                void compute(const std::vector<Eigen::VectorXd>& samples,
Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
39
                    const std::vector<Eigen::VectorXd>& observations, const Eigen::VectorXd& noises,
40
41
                    const std::vector<Eigen::VectorXd>& bl_samples = std::vector<Eigen::VectorXd>(),
                    const Eigen::VectorXd& noises_bl = Eigen::VectorXd())
Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
42
                {
Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
43
                    _raw_observations = observations;
44
                    _nb_objs = observations[0].size();
Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
45
                    auto new_observations = _scalarize_obs(observations);
Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
46
47
48
49
50
                    Model::compute(samples, new_observations, noises, bl_samples);
                }
                /// add sample will NOT be incremental (we call compute each time)
                void add_sample(const Eigen::VectorXd& sample, const Eigen::VectorXd& observation, double noise)
                {
51
52
53
                    this->_samples.push_back(sample);
                    this->_noises.conservativeResize(this->_noises.size() + 1);
                    this->_noises[this->_noises.size() - 1] = noise;
Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
54
                    _raw_observations.push_back(observation);
55

Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
56
                    this->compute(this->_samples,
57
58
                        _raw_observations, this->_noises,
                        this->_bl_samples);
Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
59
                }
Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
60
                /// WARNING: Parego does not really work with blacklisted samples
Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
61
62
                void add_bl_sample(const Eigen::VectorXd& bl_sample, double noise)
                {
63
64
65
66
                    Model::add_bl_sample(bl_sample, noise);
                    this->compute(this->_samples,
                        _raw_observations, this->_noises,
                        this->_bl_samples);
Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
67
68
69
70
                }

            protected:
                size_t _nb_objs;
Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
71
                std::vector<Eigen::VectorXd> _raw_observations;
Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
72
73
74
75
76
77
78
79
80
81
                std::vector<Eigen::VectorXd> _scalarize_obs(const std::vector<Eigen::VectorXd>& observations)
                {
                    Eigen::VectorXd lambda = tools::random_vector(_nb_objs);
                    double sum = lambda.sum();
                    lambda = lambda / sum;
                    // scalarize (Tchebycheff)
                    std::vector<Eigen::VectorXd> scalarized;
                    for (auto x : observations) {
                        double y = (lambda.array() * x.array()).maxCoeff();
                        double s = (lambda.array() * x.array()).sum();
82
                        auto v = tools::make_vector(y + Params::model_gp_parego::rho() * s);
Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
83
84
85
86
87
88
89
90
91
92
                        scalarized.push_back(v);
                    }
                    return scalarized;
                }
            };
        }
    }
}

#endif