FixedPisaNsga2.h 7.36 KB
Newer Older
adelmann's avatar
adelmann committed
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
#ifndef __FIXED_PISA_NSGA2_H__
#define __FIXED_PISA_NSGA2_H__

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include <string>
#include <sstream>
#include <vector>
#include <map>
#include <utility>
#include <fstream>

#include "Comm/types.h"
#include "Util/Types.h"
#include "Util/CmdArguments.h"
#include "Util/Statistics.h"

#include "Optimizer/Optimizer.h"
#include "Optimizer/EA/Individual.h"
#include "Optimizer/EA/Variator.h"

#include <boost/smart_ptr.hpp>
#include <boost/chrono.hpp>

#include "Util/Trace/Trace.h"


/**
 *  \class FixedPisaNsga2
 *  \brief Implementing the Variator for the PISA state machine.
 *
 *  @see http://www.tik.ee.ethz.ch/pisa/
 *
 *  The convergence behavior of the optimizer can be steered in 3 ways,
 *  corresponding command line arguments are given in brackets:
 *    - limit the number of generations (maxGenerations),
 *    - specify a target hypervolume (expected-hypervol) and tolerance
 *      (epsilon)
 *    - specify a minimal hypervolume progress (conv-hvol-prog), relative to
 *      the last generation, ((prev - new)/prev) that has to be attained to
 *      continue optimizing.
 */
template<
      template <class> class CrossoverOperator
    , template <class> class MutationOperator
>
class FixedPisaNsga2 : public Optimizer {

public:

    /**
     *  Retrieves all (for the optimizer) relevant arguments specified on the
     *  command line, initializes the variator and sets up statistics and
     *  debug traces.
     *
     *  @param[in] objectives of optimization problem
     *  @param[in] constraints of optimization problem
     *  @param[in] dvars of optimization problem
     *  @param[in] dim number of objectives
     *  @param[in] comms available to the optimizer
     *  @param[in] args the user passed on the command line
64
     *  @param[in] hypervolRef hypervolume reference point
adelmann's avatar
adelmann committed
65 66 67 68
     */
    FixedPisaNsga2(Expressions::Named_t objectives,
                   Expressions::Named_t constraints,
                   DVarContainer_t dvars, size_t dim, Comm::Bundle_t comms,
69 70
                   CmdArguments_t args,
                   std::vector<double> hypervolRef);
adelmann's avatar
adelmann committed
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 111 112 113 114 115

    ~FixedPisaNsga2();

    /// Starting selection algorithm and variator PISA state machine
    void initialize();

    /// type used in solution state exchange with other optimizers
    typedef std::vector< Individual > SolutionState_t;


protected:

    /// Write the variator config file
    void writeVariatorCfg();

    // implementing poller hooks
    bool onMessage(MPI_Status status, size_t length);
    void postPoll();

    void setupPoll() {}
    void prePoll() {
        // std::ostringstream debug;
        // debug << "IN PRE POLL: ";
        // debug << getStateString(curState_m) << std::endl;
        // progress_->log(debug);
    }
    void onStop() {}

    // helper sending evaluation requests to the pilot
    void dispatch_forward_solves();


private:

    int my_local_pid_;

    /// all PISA states
    enum PisaState_t {
          Initialize         = 0
        , InitializeSelector = 1
        , Variate            = 2
        , Select             = 3
        , Stop               = 4
        , VariatorStopped    = 5
        , VariatorTerminate  = 6
116 117 118 119 120
        /* , SelectorStopped    = 7 */
        /* , Reset              = 8 */
        /* , ReadyForReset      = 9 */
        /* , ReadyForResetS     = 10 */
        /* , Restart            = 11 */
adelmann's avatar
adelmann committed
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
    };

    std::string getStateString(PisaState_t) const;

    //FIXME:
    // selector parameters
    int seed;   /* seed for random number generator */
    int tournament;  /* parameter for tournament selection */
    size_t selector_mu_;

    /// the current state of the state machine
    PisaState_t curState_m;

    /// collect some statistics of rejected and accepted individuals
    boost::scoped_ptr<Statistics<size_t> > statistics_;

    /// type of our variator
    typedef Individual Individual_t;
    typedef Variator< Individual_t, CrossoverOperator, MutationOperator >
        Variator_t;
    boost::scoped_ptr<Variator_t> variator_m;

    std::vector<unsigned int> pp_all;
    std::vector<unsigned int> parent_queue_;
    std::set<unsigned int> archive_;
    std::set<unsigned int> to_selector_;

    // to compute the front
    std::vector<int> copies;
    std::vector<double> dist;
    std::vector< std::vector<int> > front;
    std::map<size_t, double> fitness_;

    /// communicator bundle for the optimizer
    Comm::Bundle_t comms_;

    /// buffer holding all finished job id's
    std::queue<unsigned int> finishedBuffer_m;

    /// mapping from unique job ID to individual
    std::map<size_t, boost::shared_ptr<Individual> > jobmapping_m;

    /// string of executable of the selection algorithm
    std::string execAlgo_m;

    /// indicating if initial population has been created
    bool notInitialized_m;


    /// bounds on each specified gene
    bounds_t dVarBounds_m;
    /// objectives
    Expressions::Named_t objectives_m;
    /// constraints
    Expressions::Named_t constraints_m;
    /// design variables
    DVarContainer_t dvars_m;

    /// command line arguments specified by the user
180
    CmdArguments_t args_m;
adelmann's avatar
adelmann committed
181 182 183 184

    /// size of initial population
    size_t alpha_m;
    /// number of parents the selector chooses
snuverink_j's avatar
snuverink_j committed
185
    //size_t mu_m;
adelmann's avatar
adelmann committed
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
    /// number of children the variator produces
    size_t lambda_m;
    /// number of objectives
    size_t dim_m;
    /// current generation
    size_t act_gen;
    /// maximal generation (stopping criterion)
    size_t maxGenerations_m;

    /// result file name
    std::string resultFile_m;
    std::string resultDir_m;


    // dump frequency
    int dump_freq_;

    /// convergence accuracy if maxGenerations not set
    double hvol_eps_;
    double expected_hvol_;
    double current_hvol_;
    double conv_hvol_progress_;
    double hvol_progress_;

210 211 212
    /// hypervolume reference point
    std::vector<double> hvol_ref_m;

adelmann's avatar
adelmann committed
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
    /// file header for result files contains this parameter description
    std::string file_param_descr_;

    boost::chrono::system_clock::time_point run_clock_start_;
    boost::chrono::system_clock::time_point last_clock_;

    // DEBUG output helpers
    boost::scoped_ptr<Trace> job_trace_;
    boost::scoped_ptr<Trace> progress_;


    // entry point for starting the selector side of the PISA state machine
    void startSelector(std::string filename_base);

    /// executes one loop of the PISA state machine
    void runStateMachine();

    /// passes num_individuals to the selector
    void toSelectorAndCommit(int num_individuals);

    /// how often do we exchange solutions with other optimizers
    size_t exchangeSolStateFreq_m;

    /// if necessary exchange solution state with other optimizers
    void exchangeSolutionStates();

    // Selector methods
    void selection();
    void mergeOffspring();
    void calcFitnesses();
    void calcDistances();
    void environmentalSelection();
    void matingSelection();
    int dominates(unsigned int p_ind_a, unsigned int p_ind_b);

    /// Dumps index, objective values and bit string of all individuals in
    /// global_population.
    void dumpPopulationToFile();
    void dumpPopulationToJSON();

    /**
     *  Get a random integer between [0, range]
     *  @param[in] range of random number
     *  @return random integer value between [0, range]
     */
    int irand(int range) {
        return (int) ((double) range * (double) rand() / (RAND_MAX + 1.0));
    }
};

#include "Optimizer/EA/FixedPisaNsga2.tcc"

#endif