* eoEPReduce: moved the vector tmPop in attribute in order to keep memory capacity and avoir allocation/deallocation at each call to this function

This commit is contained in:
Caner Candan 2011-05-13 11:53:47 +02:00
commit cdd2a0dc5f

View file

@ -90,81 +90,87 @@ Softer selective pressure than pure truncate
template <class EOT> class eoEPReduce : public eoReduce<EOT> template <class EOT> class eoEPReduce : public eoReduce<EOT>
{ {
public: public:
typedef typename EOT::Fitness Fitness; typedef typename EOT::Fitness Fitness;
eoEPReduce(unsigned _t_size ): eoEPReduce(unsigned _t_size ):
t_size(_t_size) t_size(_t_size)
{
if (t_size < 2)
{
eo::log << eo::warnings << "Warning: EP tournament size should be >= 2. Adjusted" << std::endl;
t_size = 2;
}
}
/// helper struct for comparing on std::pairs
// compares the scores
// uses the fitness if scores are equals ????
typedef std::pair<float, typename eoPop<EOT>::iterator> EPpair;
struct Cmp {
bool operator()(const EPpair a, const EPpair b) const
{ {
if (b.first == a.first) if (t_size < 2)
return (*b.second < *a.second); {
return b.first < a.first; eo::log << eo::warnings << "Warning: EP tournament size should be >= 2. Adjusted" << std::endl;
t_size = 2;
}
} }
};
/// helper struct for comparing on std::pairs
// compares the scores
// uses the fitness if scores are equals ????
typedef std::pair<float, typename eoPop<EOT>::iterator> EPpair;
struct Cmp {
bool operator()(const EPpair a, const EPpair b) const
{
if (b.first == a.first)
return (*b.second < *a.second);
return b.first < a.first;
}
};
void operator()(eoPop<EOT>& _newgen, unsigned _newsize) void operator()(eoPop<EOT>& _newgen, unsigned _newsize)
{ {
unsigned int presentSize = _newgen.size(); unsigned int presentSize = _newgen.size();
if (presentSize == _newsize) if (presentSize == _newsize)
return; return;
if (presentSize < _newsize) if (presentSize < _newsize)
throw std::logic_error("eoTruncate: Cannot truncate to a larger size!\n"); throw std::logic_error("eoTruncate: Cannot truncate to a larger size!\n");
std::vector<EPpair> scores(presentSize); std::vector<EPpair> scores(presentSize);
for (unsigned i=0; i<presentSize; i++) for (unsigned i=0; i<presentSize; i++)
{ {
scores[i].second = _newgen.begin()+i; scores[i].second = _newgen.begin()+i;
Fitness fit = _newgen[i].fitness(); Fitness fit = _newgen[i].fitness();
for (unsigned itourn = 0; itourn < t_size; ++itourn) for (unsigned itourn = 0; itourn < t_size; ++itourn)
{ {
const EOT & competitor = _newgen[rng.random(presentSize)]; const EOT & competitor = _newgen[rng.random(presentSize)];
if (fit > competitor.fitness()) if (fit > competitor.fitness())
scores[i].first += 1; scores[i].first += 1;
else if (fit == competitor.fitness()) else if (fit == competitor.fitness())
scores[i].first += 0.5; scores[i].first += 0.5;
} }
} }
// now we have the scores // now we have the scores
typename std::vector<EPpair>::iterator it = scores.begin() + _newsize; typename std::vector<EPpair>::iterator it = scores.begin() + _newsize;
std::nth_element(scores.begin(), it, scores.end(), Cmp()); std::nth_element(scores.begin(), it, scores.end(), Cmp());
// sort(scores.begin(), scores.end(), Cmp()); // sort(scores.begin(), scores.end(), Cmp());
unsigned j; unsigned j;
// std::cout << "Les scores apres tri\n"; // std::cout << "Les scores apres tri\n";
// for (j=0; j<scores.size(); j++) // for (j=0; j<scores.size(); j++)
// { // {
// std::cout << scores[j].first << " " << *scores[j].second << std::endl; // std::cout << scores[j].first << " " << *scores[j].second << std::endl;
// } // }
eoPop<EOT> tmPop;
tmPop.reserve(presentSize);
tmPop.clear();
for (j=0; j<_newsize; j++) for (j=0; j<_newsize; j++)
{ {
tmPop.push_back(*scores[j].second); tmPop.push_back(*scores[j].second);
} }
_newgen.swap(tmPop); _newgen.swap(tmPop);
// erase does not work, but I'm sure there is a way in STL to mark // erase does not work, but I'm sure there is a way in STL to mark
// and later delete all inside a std::vector ?????? // and later delete all inside a std::vector ??????
// this would avoid all copies here // this would avoid all copies here
// it = scores.begin() + _newsize; // it = scores.begin() + _newsize;
// while (it < scores.end()) // while (it < scores.end())
// _newgen.erase(it->second); // _newgen.erase(it->second);
} }
private: private:
unsigned t_size; unsigned t_size;
eoPop<EOT> tmPop;
}; };
/** a truncate class that does not sort, but repeatidely kills the worse. /** a truncate class that does not sort, but repeatidely kills the worse.
@ -220,7 +226,9 @@ public:
if (oldSize < _newsize) if (oldSize < _newsize)
throw std::logic_error("eoDetTournamentTruncate: Cannot truncate to a larger size!\n"); throw std::logic_error("eoDetTournamentTruncate: Cannot truncate to a larger size!\n");
// Now OK to erase some losers // Now OK to erase some losers
std::cout << "oldSize - _newsize: " << oldSize - _newsize << std::endl;
for (unsigned i=0; i<oldSize - _newsize; i++) for (unsigned i=0; i<oldSize - _newsize; i++)
{ {
//OLDCODE EOT & eo = inverse_deterministic_tournament<EOT>(_newgen, t_size); //OLDCODE EOT & eo = inverse_deterministic_tournament<EOT>(_newgen, t_size);