#include "Individual.hpp" #include #include #include #include using namespace std; Individual::Individual(size_t numObjectives) { _id = 0; _rank = -1; _constraintViolation = 0.; _crowding = 0.; _objectives.resize(numObjectives); } int Individual::getId(){return _id;} void Individual::setId(int id){_id = id;} int Individual::getRank(){return _rank;} void Individual::setRank(int rank){_rank = rank;} double Individual::getCrowdingDistance(){return _crowding;} void Individual::setCrowdingDistance(double crowdingDistance){ _crowding = crowdingDistance;} double Individual::getObjective(size_t index) { if (index >= _objectives.size()) { ostringstream msg("Objective function index out of bounds: "); msg << index; throw runtime_error(msg.str()); } return _objectives[index]; } void Individual::setObjective(size_t index, double value) { if (index >= _objectives.size()) { ostringstream msg("Objective function index out of bounds: "); msg << index; throw runtime_error(msg.str()); } _objectives[index] = value; } vector Individual::getTrace(){ return _objectives; } int checkDominance(const Individual &a, const Individual &b) { // Pretty straight-forward from NSGA-II reference impl. int i; int flag1; int flag2; flag1 = 0; flag2 = 0; if (a._constraintViolation < 0 && b._constraintViolation < 0) { if (a._constraintViolation > b._constraintViolation) { return (1); } else { if (a._constraintViolation < b._constraintViolation) { return (-1); } else { return (0); } } } else { if (a._constraintViolation < 0 && b._constraintViolation == 0) { return (-1); } else { if (a._constraintViolation == 0 && b._constraintViolation <0) { return (1); } else { for (i = 0; i < (int)a._objectives.size(); i++) { if (a._objectives[i] < b._objectives[i]) { flag1 = 1; } else { if (a._objectives[i] > b._objectives[i]) { flag2 = 1; } } } if (flag1 == 1 && flag2 == 0) { return (1); } else { if (flag1 == 0 && flag2 == 1) { return (-1); } else { return (0); } } } } } } bool Individual::winsTournamentAgainst(const Individual &opponent, mt19937 *mt) { int flag = checkDominance (*this, opponent); if (flag==1) { return true; } else if (flag==-1) { return false; } else if (this->_crowding > opponent._crowding) { return true; } else if (opponent._crowding > this->_crowding) { return false; } else { // Otherwise random choice uniform_real_distribution u(0, 1); return u(*mt) <= .5; } } void Individual::fromStream(istream & ist) { /* Read the common part: */ size_t n_ob; ist >> _id; ist >> _rank; ist >> _constraintViolation; ist >> _crowding; ist >> n_ob; _objectives.resize(n_ob); for (double& d : _objectives) ist >> d; /* Then read the representation-specific part: */ impl_from_stream(ist); } void Individual::toStream(ostream & ost) { ost.precision(17); // FIXME: Should I store and return old value? /* Write the common part: */ ost << _id << " " << _rank << " " << _constraintViolation << " " << _crowding << " " << _objectives.size() << " "; for (const double & d : _objectives) ost << d << " "; /* Write the representation-specific part: */ impl_to_stream(ost); }