New class: moeoPtrComparator, which is used to sort the population using pointers to true individuals. This improves performance in situations that individuals copy constructors are computationally expensive. Also, moeoFrontbyFrontCrowdingDiversityAssignment class is updated accordingly.

git-svn-id: svn://scm.gforge.inria.fr/svnroot/paradiseo@1430 331e1502-861f-0410-8da2-ba01fb791d7f
This commit is contained in:
wcancino 2009-02-12 13:12:23 +00:00
commit 3fede999a6
2 changed files with 96 additions and 20 deletions

View file

@ -0,0 +1,59 @@
/***************************************************************************
* Copyright (C) 2008 by Waldo Cancino *
* wcancino@icmc.usp.br *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef MOEOPTRCOMPARATOR_H_
#define MOEOPTRCOMPARATOR_H_
#include <comparator/moeoComparator.h>
/**
* Functor allowing to compare two solutions.referenced by pointers.
* Several MOEO related stuff have to sort populations according some criterion
* Instead to do this, we used a vector whose elements are pointers to true individuals
*/
template < class MOEOT >
class moeoPtrComparator : public eoBF < const MOEOT *, const MOEOT *, const bool >
{
public:
/**
* Ctor with a comparator
* @param _cmp comparator to be employed
*/
moeoPtrComparator( moeoComparator<MOEOT> & _cmp) : cmp(_cmp) {}
/** compare two const individuals */
const bool operator() (const MOEOT *ptr1, const MOEOT *ptr2)
{
return cmp(*ptr1, *ptr2);
}
/** compare two non const individuals */
const bool operator() (MOEOT *ptr1, MOEOT *ptr2)
{
return cmp(*ptr1, *ptr2);
}
private:
moeoComparator<MOEOT> &cmp;
};
#endif /*MOEOPTRCOMPARATOR_H_*/

View file

@ -1,9 +1,9 @@
/*
* <moeoFrontByFrontCrowdingDiversityAssignment.h>
* Copyright (C) DOLPHIN Project-Team, INRIA Futurs, 2006-2007
* (C) OPAC Team, LIFL, 2002-2007
* Copyright (C) DOLPHIN Project-Team, INRIA Futurs, 2006-2009
* (C) OPAC Team, LIFL, 2002-2009
*
* Arnaud Liefooghe
* Arnaud Liefooghe, Waldo Cancino
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
@ -35,11 +35,13 @@
*/
//-----------------------------------------------------------------------------
#ifndef MOEOFRONTBYFRONTCROWDINGDIVERSITYASSIGNMENT_H_
#define MOEOFRONTBYFRONTCROWDINGDIVERSITYASSIGNMENT_H_
#ifndef MOEOFRONTBYFRONTCROWDINGDIVERSITYASSIGNMENT2_H_
#define MOEOFRONTBYFRONTCROWDINGDIVERSITYASSIGNMENT2_H_
#include <diversity/moeoCrowdingDiversityAssignment.h>
#include <comparator/moeoFitnessThenDiversityComparator.h>
#include <comparator/moeoPtrComparator.h>
/**
* Diversity assignment sheme based on crowding proposed in:
@ -67,7 +69,6 @@ class moeoFrontByFrontCrowdingDiversityAssignment : public moeoCrowdingDiversity
std::cout << "WARNING : updateByDeleting not implemented in moeoFrontByFrontCrowdingDistanceDiversityAssignment" << std::endl;
}
private:
using moeoCrowdingDiversityAssignment < MOEOT >::inf;
@ -77,7 +78,8 @@ class moeoFrontByFrontCrowdingDiversityAssignment : public moeoCrowdingDiversity
* Sets the distance values
* @param _pop the population
*/
void setDistances (eoPop < MOEOT > & _pop)
void setDistances (eoPop <MOEOT> & _pop)
{
unsigned int a,b;
double min, max, distance;
@ -89,18 +91,28 @@ class moeoFrontByFrontCrowdingDiversityAssignment : public moeoCrowdingDiversity
}
// sort the whole pop according to fitness values
moeoFitnessThenDiversityComparator < MOEOT > fitnessComparator;
std::sort(_pop.begin(), _pop.end(), fitnessComparator);
std::vector<MOEOT *> sortedptrpop;
sortedptrpop.resize(_pop.size());
// due to intensive sort operations for this diversity assignment,
// it is more efficient to perform sorts using only pointers to the
// population members in order to avoid copy of individuals
for(int i=0; i< _pop.size(); i++) sortedptrpop[i] = & (_pop[i]);
//sort the pointers to population members
moeoPtrComparator<MOEOT> cmp2( fitnessComparator);
std::sort(sortedptrpop.begin(), sortedptrpop.end(), cmp2);
// compute the crowding distance values for every individual "front" by "front" (front : from a to b)
a = 0; // the front starts at a
while (a < _pop.size())
{
b = lastIndex(_pop,a); // the front ends at b
b = lastIndex(sortedptrpop,a); // the front ends at b
//b = lastIndex(_pop,a); // the front ends at b
// if there is less than 2 individuals in the front...
if ((b-a) < 2)
{
for (unsigned int i=a; i<=b; i++)
{
_pop[i].diversity(inf());
sortedptrpop[i]->diversity(inf());
//_pop[i].diversity(inf());
}
}
// else...
@ -111,10 +123,12 @@ class moeoFrontByFrontCrowdingDiversityAssignment : public moeoCrowdingDiversity
{
// sort in the descending order using the values of the objective 'obj'
moeoOneObjectiveComparator < MOEOT > objComp(obj);
std::sort(_pop.begin()+a, _pop.begin()+b+1, objComp);
moeoPtrComparator<MOEOT> cmp2( objComp );
std::sort(sortedptrpop.begin(), sortedptrpop.end(), cmp2);
// min & max
min = _pop[b].objectiveVector()[obj];
max = _pop[a].objectiveVector()[obj];
min = (sortedptrpop[b])->objectiveVector()[obj];
max = (sortedptrpop[a])->objectiveVector()[obj];
// avoid extreme case
if (min == max)
{
@ -122,13 +136,13 @@ class moeoFrontByFrontCrowdingDiversityAssignment : public moeoCrowdingDiversity
max += tiny();
}
// set the diversity value to infiny for min and max
_pop[a].diversity(inf());
_pop[b].diversity(inf());
sortedptrpop[a]->diversity(inf());
sortedptrpop[b]->diversity(inf());
// set the diversity values for the other individuals
for (unsigned int i=a+1; i<b; i++)
{
distance = (_pop[i-1].objectiveVector()[obj] - _pop[i+1].objectiveVector()[obj]) / (max-min);
_pop[i].diversity(_pop[i].diversity() + distance);
distance = ( sortedptrpop[i-1]->objectiveVector()[obj] - sortedptrpop[i+1]->objectiveVector()[obj] ) / (max-min);
sortedptrpop[i]->diversity(sortedptrpop[i]->diversity() + distance);
}
}
}
@ -138,21 +152,24 @@ class moeoFrontByFrontCrowdingDiversityAssignment : public moeoCrowdingDiversity
}
/**
* Returns the index of the last individual having the same fitness value than _pop[_start]
* @param _pop the population
* @param _pop the vector of pointers to population individuals
* @param _start the index to start from
*/
unsigned int lastIndex (eoPop < MOEOT > & _pop, unsigned int _start)
unsigned int lastIndex (std::vector<MOEOT *> & _pop, unsigned int _start)
{
unsigned int i=_start;
while ( (i<_pop.size()-1) && (_pop[i].fitness()==_pop[i+1].fitness()) )
while ( (i<_pop.size()-1) && (_pop[i]->fitness()==_pop[i+1]->fitness()) )
{
i++;
}
return i;
}
};
#endif /*MOEOFRONTBYFRONTCROWDINGDIVERSITYASSIGNMENT_H_*/