git-svn-id: svn://scm.gforge.inria.fr/svnroot/paradiseo@36 331e1502-861f-0410-8da2-ba01fb791d7f

This commit is contained in:
legrand 2006-12-12 14:46:07 +00:00
commit c7d3cc755c
154 changed files with 13175 additions and 0 deletions

View file

@ -0,0 +1 @@
# Nothing to compile !

View file

@ -0,0 +1,94 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// moeoBinaryMetricSavingUpdater.h
// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2006
/*
This library...
Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEOBINARYMETRICSAVINGUPDATER_H_
#define MOEOBINARYMETRICSAVINGUPDATER_H_
#include <fstream>
#include <string>
#include <eoPop.h>
#include <utils/eoUpdater.h>
#include <metric/moeoMetric.h>
/**
* This class allows to save the progression of a binary metric comparing the fitness values of the current population (or archive)
* with the fitness values of the population (or archive) of the generation (n-1) into a file
*/
template < class EOT > class moeoBinaryMetricSavingUpdater:public eoUpdater
{
public:
/**
* The fitness type of a solution
*/
typedef typename EOT::Fitness EOFitness;
/**
* Ctor
* @param _metric the binary metric comparing two Pareto sets
* @param _pop the main population
* @param _filename the target filename
*/
moeoBinaryMetricSavingUpdater (moeoVectorVsVectorBM < EOT, double >&_metric,
const eoPop < EOT > &_pop,
std::string _filename):metric (_metric),
pop (_pop), filename (_filename), counter (1)
{
}
/**
* Saves the metric's value for the current generation
*/
void operator () ()
{
if (pop.size ())
{
if (firstGen)
{
firstGen = false;
}
else
{
// creation of the two Pareto sets
std::vector < EOFitness > from;
std::vector < EOFitness > to;
for (unsigned i = 0; i < pop.size (); i++)
from.push_back (pop[i].fitness ());
for (unsigned i = 0; i < oldPop.size (); i++)
to.push_back (oldPop[i].fitness ());
// writing the result into the file
std::ofstream f (filename.c_str (), std::ios::app);
f << counter++ << ' ' << metric (from, to) << std::endl;
f.close ();
}
oldPop = pop;
}
}
private:
/** binary metric comparing two Pareto sets */
moeoVectorVsVectorBM < EOT, double >&metric;
/** main population */
const eoPop < EOT > &pop;
/** (n-1) population */
eoPop < EOT > oldPop;
/** target filename */
std::string filename;
/** is it the first generation ? */
bool firstGen;
/** counter */
unsigned counter;
};
#endif /*MOEOBINARYMETRICSAVINGUPDATER_H_ */

View file

@ -0,0 +1,116 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// moeoContributionMetric.h
// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2006
/*
This library...
Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEOCONTRIBUTIONMETRIC_H_
#define MOEOCONTRIBUTIONMETRIC_H_
#include <metric/moeoMetric.h>
/**
* The contribution metric evaluates the proportion of non-dominated solutions given by a Pareto set relatively to another Pareto set
*
* (Meunier, Talbi, Reininger: 'A multiobjective genetic algorithm for radio network optimization', in Proc. of the 2000 Congress on Evolutionary Computation, IEEE Press, pp. 317-324)
*/
template < class EOT > class moeoContributionMetric:public moeoVectorVsVectorBM < EOT,
double >
{
public:
/**
* The fitness type of a solution
*/
typedef typename EOT::Fitness EOFitness;
/**
* Returns the contribution of the Pareto set '_set1' relatively to the Pareto set '_set2'
* @param _set1 the first Pareto set
* @param _set2 the second Pareto set
*/
double operator () (const std::vector < EOFitness > &_set1,
const std::vector < EOFitness > &_set2)
{
unsigned c = card_C (_set1, _set2);
unsigned w1 = card_W (_set1, _set2);
unsigned n1 = card_N (_set1, _set2);
unsigned w2 = card_W (_set2, _set1);
unsigned n2 = card_N (_set2, _set1);
return (double) (c / 2.0 + w1 + n1) / (c + w1 + n1 + w2 + n2);
}
private:
/**
* Returns the number of solutions both in '_set1' and '_set2'
* @param _set1 the first Pareto set
* @param _set2 the second Pareto set
*/
unsigned card_C (const std::vector < EOFitness > &_set1,
const std::vector < EOFitness > &_set2)
{
unsigned c = 0;
for (unsigned i = 0; i < _set1.size (); i++)
for (unsigned j = 0; j < _set2.size (); j++)
if (_set1[i] == _set2[j])
{
c++;
break;
}
return c;
}
/**
* Returns the number of solutions in '_set1' dominating at least one solution of '_set2'
* @param _set1 the first Pareto set
* @param _set2 the second Pareto set
*/
unsigned card_W (const std::vector < EOFitness > &_set1,
const std::vector < EOFitness > &_set2)
{
unsigned w = 0;
for (unsigned i = 0; i < _set1.size (); i++)
for (unsigned j = 0; j < _set2.size (); j++)
if (_set1[i].dominates (_set2[j]))
{
w++;
break;
}
return w;
}
/**
* Returns the number of solutions in '_set1' having no relation of dominance with those from '_set2'
* @param _set1 the first Pareto set
* @param _set2 the second Pareto set
*/
unsigned card_N (const std::vector < EOFitness > &_set1,
const std::vector < EOFitness > &_set2)
{
unsigned n = 0;
for (unsigned i = 0; i < _set1.size (); i++)
{
bool domin_rel = false;
for (unsigned j = 0; j < _set2.size (); j++)
if (_set1[i].dominates (_set2[j]) || _set2[j].dominates (_set1[i]))
{
domin_rel = true;
break;
}
if (!domin_rel)
n++;
}
return n;
}
};
#endif /*MOEOCONTRIBUTIONMETRIC_H_ */

View file

@ -0,0 +1,179 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// moeoEntropyMetric.h
// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2006
/*
This library...
Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEOENTROPYMETRIC_H_
#define MOEOENTROPYMETRIC_H_
#include <metric/moeoMetric.h>
/**
* The entropy gives an idea of the diversity of a Pareto set relatively to another Pareto set
*
* (Basseur, Seynhaeve, Talbi: 'Design of Multi-objective Evolutionary Algorithms: Application to the Flow-shop Scheduling Problem', in Proc. of the 2002 Congress on Evolutionary Computation, IEEE Press, pp. 1155-1156)
*/
template < class EOT > class moeoEntropyMetric:public moeoVectorVsVectorBM < EOT,
double >
{
public:
/**
* The fitness type of a solution
*/
typedef typename EOT::Fitness EOFitness;
/**
* Returns the entropy of the Pareto set '_set1' relatively to the Pareto set '_set2'
* @param _set1 the first Pareto set
* @param _set2 the second Pareto set
*/
double operator () (const std::vector < EOFitness > &_set1,
const std::vector < EOFitness > &_set2)
{
// normalization
std::vector < EOFitness > set1 = _set1;
std::vector < EOFitness > set2 = _set2;
removeDominated (set1);
removeDominated (set2);
prenormalize (set1);
normalize (set1);
normalize (set2);
// making of PO*
std::vector < EOFitness > star; // rotf :-)
computeUnion (set1, set2, star);
removeDominated (star);
// making of PO1 U PO*
std::vector < EOFitness > union_set1_star; // rotf again ...
computeUnion (set1, star, union_set1_star);
unsigned C = union_set1_star.size ();
float omega = 0;
float entropy = 0;
for (unsigned i = 0; i < C; i++)
{
unsigned N_i =
howManyInNicheOf (union_set1_star, union_set1_star[i],
star.size ());
unsigned n_i =
howManyInNicheOf (set1, union_set1_star[i], star.size ());
if (n_i > 0)
{
omega += 1.0 / N_i;
entropy +=
(float) n_i / (N_i * C) * log (((float) n_i / C) / log (2.0));
}
}
entropy /= -log (omega);
entropy *= log (2.0);
return entropy;
}
private:
std::vector < double >vect_min_val;
std::vector < double >vect_max_val;
void removeDominated (std::vector < EOFitness > &_f)
{
for (unsigned i = 0; i < _f.size (); i++)
{
bool dom = false;
for (unsigned j = 0; j < _f.size (); j++)
if (i != j && _f[j].dominates (_f[i]))
{
dom = true;
break;
}
if (dom)
{
_f[i] = _f.back ();
_f.pop_back ();
i--;
}
}
}
void prenormalize (const std::vector < EOFitness > &_f)
{
vect_min_val.clear ();
vect_max_val.clear ();
for (unsigned char i = 0; i < EOFitness::fitness_traits::nObjectives ();
i++)
{
float min_val = _f.front ()[i], max_val = min_val;
for (unsigned j = 1; j < _f.size (); j++)
{
if (_f[j][i] < min_val)
min_val = _f[j][i];
if (_f[j][i] > max_val)
max_val = _f[j][i];
}
vect_min_val.push_back (min_val);
vect_max_val.push_back (max_val);
}
}
void normalize (std::vector < EOFitness > &_f)
{
for (unsigned i = 0; i < EOFitness::fitness_traits::nObjectives (); i++)
for (unsigned j = 0; j < _f.size (); j++)
_f[j][i] =
(_f[j][i] - vect_min_val[i]) / (vect_max_val[i] - vect_min_val[i]);
}
void computeUnion (const std::vector < EOFitness > &_f1,
const std::vector < EOFitness > &_f2,
std::vector < EOFitness > &_f)
{
_f = _f1;
for (unsigned i = 0; i < _f2.size (); i++)
{
bool b = false;
for (unsigned j = 0; j < _f1.size (); j++)
if (_f1[j] == _f2[i])
{
b = true;
break;
}
if (!b)
_f.push_back (_f2[i]);
}
}
unsigned howManyInNicheOf (const std::vector < EOFitness > &_f,
const EOFitness & _s, unsigned _size)
{
unsigned n = 0;
for (unsigned i = 0; i < _f.size (); i++)
{
if (euclidianDistance (_f[i], _s) < (_s.size () / (double) _size))
n++;
}
return n;
}
double euclidianDistance (const EOFitness & _set1, const EOFitness & _to,
unsigned _deg = 2)
{
double dist = 0;
for (unsigned i = 0; i < _set1.size (); i++)
dist += pow (fabs (_set1[i] - _to[i]), (int) _deg);
return pow (dist, 1.0 / _deg);
}
};
#endif /*MOEOENTROPYMETRIC_H_ */

View file

@ -0,0 +1,106 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// moeoMetric.h
// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2006
/*
This library...
Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEOMETRIC_H_
#define MOEOMETRIC_H_
#include <eoFunctor.h>
/**
* Base class for performance metrics (also called quality indicators)
*/
class moeoMetric:public eoFunctorBase
{
};
/**
* Base class for unary metrics
*/
template < class A, class R > class moeoUM:public eoUF < A, R >,
public moeoMetric
{
};
/**
* Base class for binary metrics
*/
template < class A1, class A2, class R > class moeoBM:public eoBF < A1, A2, R >,
public moeoMetric
{
};
/**
* Base class for unary metrics dedicated to the performance evaluation of a single solution's Pareto fitness
*/
template < class EOT, class R, class EOFitness = typename EOT::Fitness > class moeoSolutionUM:public moeoUM <
const
EOFitness &,
R >
{
};
/**
* Base class for unary metrics dedicated to the performance evaluation of a Pareto set (a vector of Pareto fitnesses)
*/
template < class EOT, class R, class EOFitness = typename EOT::Fitness > class moeoVectorUM:public moeoUM <
const
std::vector <
EOFitness > &,
R >
{
};
/**
* Base class for binary metrics dedicated to the performance comparison between two solutions's Pareto fitnesses
*/
template < class EOT, class R, class EOFitness = typename EOT::Fitness > class moeoSolutionVsSolutionBM:public moeoBM <
const
EOFitness &, const
EOFitness &,
R >
{
};
/**
* Base class for binary metrics dedicated to the performance comparison between a Pareto set (a vector of Pareto fitnesses) and a single solution's Pareto fitness
*/
template < class EOT, class R, class EOFitness = typename EOT::Fitness > class moeoVectorVsSolutionBM:public moeoBM <
const
std::vector <
EOFitness > &, const
EOFitness &,
R >
{
};
/**
* Base class for binary metrics dedicated to the performance comparison between two Pareto sets (two vectors of Pareto fitnesses)
*/
template < class EOT, class R, class EOFitness = typename EOT::Fitness > class moeoVectorVsVectorBM:public moeoBM <
const
std::vector <
EOFitness > &, const
std::vector <
EOFitness > &,
R >
{
};
#endif /*MOEOMETRIC_H_ */

View file

@ -0,0 +1,18 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// moeo
// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2006
/*
This library...
Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEO_
#define MOEO_
#include <moeo.h>
#endif /*MOEO_H_*/

View file

@ -0,0 +1,31 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// moeo.h
// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2006
/*
This library...
Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEO_H_
#define MOEO_H_
#include <eo>
#include <moeoArchiveFitnessSavingUpdater.h>
#include <moeoArchiveUpdater.h>
#include <moeoArchive.h>
#include <moeoCombinedMOLS.h>
#include <moeoHybridMOLS.h>
#include <moeoMOLS.h>
#include <moeoReplacement.h>
#include <moeoSelectOneFromPopAndArch.h>
#include <metric/moeoBinaryMetricSavingUpdater.h>
#include <metric/moeoContributionMetric.h>
#include <metric/moeoEntropyMetric.h>
#include <metric/moeoMetric.h>
#endif /*MOEO_H_ */

View file

@ -0,0 +1,106 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// moeoArchive.h
// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2006
/*
This library...
Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEOARCHIVE_H_
#define MOEOARCHIVE_H_
#include <eoPop.h>
/**
* An archive is a secondary population that stores non-dominated solutions
*/
template < class EOT > class moeoArchive:public eoPop < EOT >
{
public:
using std::vector < EOT >::size;
using std::vector < EOT >::operator[];
using std::vector < EOT >::back;
using std::vector < EOT >::pop_back;
/**
* The fitness type of a solution
*/
typedef typename EOT::Fitness EOFitness;
/**
* Returns true if the current archive dominates _fit
* @param _fit the (Pareto) fitness to compare with the current archive
*/
bool dominates (const EOFitness & _fit) const
{
for (unsigned i = 0; i < size; i++)
if (operator[](i).fitness ().dominates (_fit))
return true;
return false;
}
/**
* Returns true if the current archive contains _fit
* @param _fit the (Pareto) fitness to search within the current archive
*/
bool contains (const EOFitness & _fit) const
{
for (unsigned i = 0; i < size; i++)
if (operator[](i).fitness () == _fit)
return true;
return false;
}
/**
* Updates the archive with a given individual _eo
* @param _eo the given individual
*/
void update (const EOT & _eo)
{
// Removing the dominated solutions from the archive
for (unsigned j = 0; j < size ();)
{
if (_eo.fitness ().dominates (operator[](j).fitness ()))
{
operator[](j) = back ();
pop_back ();
}
else if (_eo.fitness () == operator[](j).fitness ())
{
operator[](j) = back ();
pop_back ();
}
else
j++;
}
// Dominated ?
bool dom = false;
for (unsigned j = 0; j < size (); j++)
if (operator [](j).fitness ().dominates (_eo.fitness ()))
{
dom = true;
break;
}
if (!dom)
push_back (_eo);
}
/**
* Updates the archive with a given population _pop
* @param _pop the given population
*/
void update (const eoPop < EOT > &_pop)
{
for (unsigned i = 0; i < _pop.size (); i++)
update (_pop[i]);
}
};
#endif /*MOEOARCHIVE_H_ */

View file

@ -0,0 +1,73 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// moeoArchiveFitnessSavingUpdater.h
// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2006
/*
This library...
Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEOARCHIVEFITNESSSAVINGUPDATER_H_
#define MOEOARCHIVEFITNESSSAVINGUPDATER_H_
#include <fstream>
#include <string>
#include <eoPop.h>
#include <utils/eoUpdater.h>
#include <moeoArchive.h>
#define MAX_BUFFER_SIZE 1000
/**
* This class allows to save the fitnesses of solutions contained in an archive into a file at each generation.
*/
template < class EOT > class moeoArchiveFitnessSavingUpdater:public eoUpdater
{
public:
/**
* Ctor
* @param _arch local archive
* @param _filename target filename
* @param _id own ID
*/
moeoArchiveFitnessSavingUpdater (moeoArchive < EOT > &_arch, const std::string & _filename = "Res/Arch", int _id = -1):arch (_arch), filename (_filename), id (_id),
counter
(0)
{
}
/**
* Saves the fitness of the archive's members into the file
*/
void operator () ()
{
char buff[MAX_BUFFER_SIZE];
if (id == -1)
sprintf (buff, "%s.%u", filename.c_str (), counter++);
else
sprintf (buff, "%s.%u.%u", filename.c_str (), id, counter++);
std::ofstream f (buff);
for (unsigned i = 0; i < arch.size (); i++)
f << arch[i].fitness () << std::endl;
f.close ();
}
private:
/** local archive */
moeoArchive < EOT > &arch;
/** target filename */
std::string filename;
/** own ID */
int id;
/** counter */
unsigned counter;
};
#endif /*MOEOARCHIVEFITNESSSAVINGUPDATER_H_ */

View file

@ -0,0 +1,56 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// moeoArchiveUpdater.h
// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2006
/*
This library...
Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEOARCHIVEUPDATER_H_
#define MOEOARCHIVEUPDATER_H_
#include <eoPop.h>
#include <utils/eoUpdater.h>
#include <moeoArchive.h>
/**
* This class allows to update the archive at each generation with newly found non-dominated solutions
*/
template < class EOT > class moeoArchiveUpdater:public eoUpdater
{
public:
/**
* Ctor
* @param _arch an archive of non-dominated solutions
* @param _pop the main population
*/
moeoArchiveUpdater (moeoArchive < EOT > &_arch,
const eoPop < EOT > &_pop):arch (_arch), pop (_pop)
{
}
/**
* Updates the archive with newly found non-dominated solutions contained in the main population
*/
void operator () ()
{
arch.update (pop);
}
private:
/** the archive of non-dominated solutions */
moeoArchive < EOT > &arch;
/** the main population */
const eoPop < EOT > &pop;
};
#endif /*MOEOARCHIVEUPDATER_H_ */

View file

@ -0,0 +1,71 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// moeoCombinedMOLS.h
// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2006
/*
This library...
Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEOCOMBINEDMOLS_H_
#define MOEOCOMBINEDMOLS_H_
#include <eoEvalFunc.h>
#include <moeoArchive.h>
#include <moeoMOLS.h>
/**
* This class allows to embed a set of local searches that are sequentially applied,
* and so working and updating the same archive of non-dominated solutions
*/
template < class EOT > class moeoCombinedMOLS:public moeoMOLS < EOT >
{
public:
/**
* Ctor
* @param _eval the full evaluator of a solution
* @param _first_ls the first multi-objective local search to add
*/
moeoCombinedMOLS (eoEvalFunc < EOT > &_eval, moeoMOLS < EOT > &_first_ls):eval
(_eval)
{
combinedMOLS.push_back (&_first_ls);
}
/**
* Adds a new local search to combine
* @param _ls the multi-objective local search to add
*/
void add (moeoMOLS < EOT > &_ls)
{
combinedMOLS.push_back (&_ls);
}
/**
* Gives a new solution in order to explore the neigborhood.
* The new non-dominated solutions are added to the archive
* @param _eo the solution
* @param _arch the archive of non-dominated solutions
*/
void operator () (const EOT & _eo, moeoArchive < EOT > &_arch)
{
eval (const_cast < EOT & >(_eo));
for (unsigned i = 0; i < combinedMOLS.size (); i++)
combinedMOLS[i]->operator ()(_eo, _arch);
}
private:
/** the full evaluator of a solution */
eoEvalFunc < EOT > &eval;
/** the vector that contains the combined MOLS */
std::vector < moeoMOLS < EOT > *>combinedMOLS;
};
#endif /*MOEOCOMBINEDMOLS_H_ */

View file

@ -0,0 +1,74 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// moeoHybridMOLS.h
// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2006
/*
This library...
Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEOHYBRIDMOLS_H_
#define MOEOHYBRIDMOLS_H_
#include <eoContinue.h>
#include <eoPop.h>
#include <eoUpdater.h>
#include <eoSelect.h>
#include <moeoArchive.h>
#include <moeoMOLS.h>
/**
* This class allows to apply a multi-objective local search to a number of selected individuals contained in the archive
* at every generation until a stopping criteria is verified.
*/
template < class EOT > class moeoHybridMOLS:public eoUpdater
{
public:
/**
* Ctor
* @param _term stopping criteria
* @param _select selector
* @param _mols a multi-objective local search
* @param _arch the archive
*/
eoHybridMOLS (eoContinue < EOT > &_term, eoSelect < EOT > &_select, moeoMOLS < EOT > &_mols, moeoArchive < EOT > &_arch):term (_term), select (_select), mols (_mols),
arch
(_arch)
{
}
/**
* Applies the multi-objective local search to selected individuals contained in the archive if the stopping criteria is not verified
*/
void operator () ()
{
if (!cont (arch))
{
// selection of solutions
eoPop < EOT > selectedSolutions;
select (arch, selectedSolutions);
// apply the local search to every selected solution
for (unsigned i = 0; i < selectedSolutions.size (); i++)
mols (selectedSolutions[i], arch);
}
}
private:
/** stopping criteria*/
eoContinue < EOT > &term;
/** selector */
eoSelect < EOT > &select;
/** multi-objective local search */
moeoMOLS < EOT > &mols;
/** archive */
moeoArchive < EOT > &arch;
};
#endif /*MOEOHYBRIDMOLS_H_ */

View file

@ -0,0 +1,28 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// moeoMOLS.h
// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2006
/*
This library...
Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEOMOLS_H_
#define MOEOMOLS_H_
#include <eoFunctor.h>
#include <moeoArchive.h>
/**
* Abstract class for local searches applied to multi-objective optimization.
* Starting from only one solution, it produces a set of new non-dominated solutions.
*/
template < class EOT > class moeoMOLS:public eoBF < const EOT &, moeoArchive < EOT > &,
void >
{
};
#endif /*MOEOMOLS_H_ */

View file

@ -0,0 +1,169 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// moeoReplacement.h
// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2006
/*
This library...
Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEOREPLACEMENT_H_
#define MOEOREPLACEMENT_H_
#include <eoPerf2Worth.h>
#include <eoPop.h>
#include <eoReplacement.h>
/**
* Replacement strategy for multi-objective optimization
*/
template < class EOT, class WorthT > class moeoReplacement:public eoReplacement <
EOT >
{
};
/**
* Keep all the best individuals
* (almost cut-and-pasted from eoNDPlusReplacement, (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2002)
*/
template < class EOT, class WorthT =
double >class moeoElitistReplacement:public moeoReplacement < EOT, WorthT >
{
public:
/**
* constructor
* @param _perf2worth the functor class to transform raw fitnesses into fitness for selection
*/
moeoElitistReplacement (eoPerf2Worth < EOT,
WorthT > &_perf2worth):perf2worth (_perf2worth)
{
}
/**
* replacement - result in _parents
* @param _parents parents population
* @param _offspring offspring population
*/
void operator () (eoPop < EOT > &_parents, eoPop < EOT > &_offspring)
{
unsigned size = _parents.size ();
_parents.reserve (_parents.size () + _offspring.size ());
copy (_offspring.begin (), _offspring.end (), back_inserter (_parents));
// calculate worths
perf2worth (_parents);
perf2worth.sort_pop (_parents);
perf2worth.resize (_parents, size);
_offspring.clear ();
}
private:
/** the functor object to transform raw fitnesses into fitness for selection */
eoPerf2Worth < EOT, WorthT > &perf2worth;
};
/**
* Same than moeoElitistReplacement except that distinct individuals are privilegied
*/
template < class EOT, class WorthT =
double >class moeoDisctinctElitistReplacement:public moeoReplacement < EOT,
WorthT >
{
public:
/**
* constructor
* @param _perf2worth the functor class to transform raw fitnesses into fitness for selection
*/
moeoDisctinctElitistReplacement (eoPerf2Worth < EOT,
WorthT >
&_perf2worth):perf2worth (_perf2worth)
{
}
/**
* replacement - result in _parents
* @param _parents parents population
* @param _offspring offspring population
*/
void operator () (eoPop < EOT > &_parents, eoPop < EOT > &_offspring)
{
unsigned size = _parents.size ();
_parents.reserve (_parents.size () + _offspring.size ());
copy (_offspring.begin (), _offspring.end (), back_inserter (_parents));
// creation of the new population (of size 'size')
createNewPop (_parents, size);
_offspring.clear ();
}
private:
/** the functor object to transform raw fitnesses into fitness for selection */
eoPerf2Worth < EOT, WorthT > &perf2worth;
/**
* creation of the new population of size _size
* @param _pop the initial population (will be modified)
* @param _size the size of the population to create
*/
void createNewPop (eoPop < EOT > &_pop, unsigned _size)
{
// the number of occurences for each individual
std::map < EOT, unsigned >nb_occurences;
for (unsigned i = 0; i < _pop.size (); i++)
nb_occurences[_pop[i]] = 0;
// the new population
eoPop < EOT > new_pop;
new_pop.reserve (_pop.size ());
for (unsigned i = 0; i < _pop.size (); i++)
{
if (nb_occurences[_pop[i]] == 0)
new_pop.push_back (_pop[i]);
nb_occurences[_pop[i]]++;
}
// calculate worths (on the new population)
perf2worth (new_pop);
perf2worth.sort_pop (new_pop);
// if case there's not enough individuals in the population...
unsigned new_pop_size_init = new_pop.size ();
unsigned k = 0;
while (new_pop.size () < _size)
{
if (k < new_pop_size_init)
{
if (nb_occurences[new_pop[k]] > 1)
{
new_pop.push_back (new_pop[k]);
nb_occurences[new_pop[k]]--;
}
k++;
}
else
k = 0;
}
// resize and swap the populations
perf2worth.resize (new_pop, _size);
_pop.resize (_size);
_pop.swap (new_pop);
}
};
#endif /*MOEOREPLACEMENT_H_ */

View file

@ -0,0 +1,93 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// moeoSelectOneFormPopAndArch.h
// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2006
/*
This library...
Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEOSELECTONEFROMPOPANDARCH_H_
#define MOEOSELECTONEFROMPOPANDARCH_H_
#include <eoPop.h>
#include <eoRandomSelect.h>
#include <eoSelectOne.h>
#include <utils/eoRNG.h>
#include <moeoArchive.h>
/**
* Elitist selection process that consists in choosing individuals in the archive as well as in the current population.
*/
template < class EOT > class moeoSelectOneFromPopAndArch:public eoSelectOne <
EOT >
{
public:
/**
* Ctor
* @param _popSelectOne the population's selection operator
* @param _archSelectOne the archive's selection operator
* @param _arch the archive
* @param _ratioFromPop the ratio of selected individuals from the population
*/
moeoSelectOneFromPopAndArch (eoSelectOne < EOT > &_popSelectOne, eoSelectOne < EOT > _archSelectOne, moeoArchive < EOT > &_arch, double _ratioFromPop = 0.5):popSelectOne (_popSelectOne), archSelectOne (_archSelectOne), arch (_arch),
ratioFromPop
(_ratioFromPop)
{
}
/**
* Ctor - the archive's selection operator is a random selector
* @param _popSelectOne the population's selection operator
* @param _arch the archive
* @param _ratioFromPop the ratio of selected individuals from the population
*/
moeoSelectOneFromPopAndArch (eoSelectOne < EOT > &_popSelectOne, moeoArchive < EOT > &_arch, double _ratioFromPop = 0.5):popSelectOne (_popSelectOne), archSelectOne (randomSelect), arch (_arch),
ratioFromPop
(_ratioFromPop)
{
}
/**
* The selection process
*/
virtual const EOT & operator () (const eoPop < EOT > &pop)
{
if (arch.size () > 0)
if (rng.flip (ratioFromPop))
return popSelectOne (pop);
else
return archSelectOne (arch);
else
return popSelectOne (pop);
}
/**
* Setups some population stats
*/
virtual void setup (const eoPop < EOT > &_pop)
{
popSelectOne.setup (_pop);
}
private:
/** The population's selection operator */
eoSelectOne < EOT > &popSelectOne;
/** The archive's selection operator */
eoSelectOne < EOT > &archSelectOne;
/** the archive */
moeoArchive < EOT > &arch;
/** the ratio of selected individuals from the population*/
double ratioFromPop;
/** the random selection operator */
eoRandomSelect < EOT > randomSelect;
};
#endif /*MOEOSELECTONEFROMPOPANDARCH_H_ */

View file

@ -0,0 +1,420 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
// "eoBinaryQualityIndicator.h"
// (c) OPAC Team, LIFL, June 2006
/* This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: Arnaud.Liefooghe@lifl.fr
*/
#ifndef _eoBinaryQualityIndicator_h
#define _eoBinaryQualityIndicator_h
// for std::exceptions
#include <stdexcept>
// for eoBF
#include <eoFunctor.h>
/**
* Functor
* Binary quality indicator
* Binary performance measure to use in the replacement selection process of IBEA (Indicator-Based Evolutionary Algorithm)
* Of course, EOFitness needs to be an eoParetoFitness object
*/
template < class EOFitness > class eoBinaryQualityIndicator:public eoBF < const EOFitness &, const EOFitness &,
double >
{
public:
/**
* constructor
*/
eoBinaryQualityIndicator ():eoBF < const EOFitness &, const EOFitness &,
double >()
{
bounds.reserve (traits::nObjectives ());
bounds.resize (traits::nObjectives ());
}
/**
* set the bounds for objective _iObj
* @param unsigned _iObj the index of the objective
* @param double _min the minimum value
* @param double _max the maximum value
*/
void setBounds (const unsigned _iObj, const double _min, const double _max)
{
bounds[_iObj] = Range (_min, _max);
}
protected:
/**
* Private class to represent the bounds
*/
class Range
{
public:
Range ()
{
min = 0;
max = 0;
r = 0;
}
Range (const double _min, const double _max)
{
min = _min;
max = _max;
r = max - min;
if (r < 0)
throw std::logic_error ("Negative range in eoBinaryQualityIndicator");
}
double minimum ()
{
return min;
}
double maximum ()
{
return max;
}
double range ()
{
return r;
}
private:
double min, max, r;
};
/** range (min and max double value) for each objective */
std::vector < Range > bounds;
private:
/** fitness traits */
typedef typename EOFitness::fitness_traits traits;
};
/**
* Functor
* Additive binary epsilon indicator for eoParetoFitness
*/
template < class EOFitness > class eoAdditiveBinaryEpsilonIndicator:public eoBinaryQualityIndicator <
EOFitness
>
{
public:
/**
* constructor
*/
eoAdditiveBinaryEpsilonIndicator ():eoBinaryQualityIndicator < EOFitness >
()
{
}
/**
* computation of the maximum epsilon value by which individual _eo1 must be
* decreased in all objectives such that individual _eo2 is weakly dominated
* (do not forget to set the bounds before the call of this function)
* @param EOFitness & _fitness_eo1 the fitness of the first individual
* @param EOFitness & _fitness_eo2 the fitness of the second individual
*/
double operator () (const EOFitness & _fitness_eo1,
const EOFitness & _fitness_eo2)
{
double epsilon, tmp;
// computation of the epsilon value for the first objective
epsilon = epsilonValue (_fitness_eo1, _fitness_eo2, 0);
// computation of the epsilon value for other objectives
for (unsigned i = 1; i < traits::nObjectives (); i++)
{
tmp = epsilonValue (_fitness_eo1, _fitness_eo2, i);
epsilon = std::max (epsilon, tmp);
}
// the maximum epsilon value
return epsilon;
}
private:
/** fitness traits */
typedef typename EOFitness::fitness_traits traits;
/** bounds */
using eoAdditiveBinaryEpsilonIndicator < EOFitness >::bounds;
/**
* computation of the epsilon value by which individual _eo1 must be
* decreased in the objective _iObj such that individual _eo2 is weakly dominated
* @param EOFitness & _fitness_eo1 the fitness of the first individual
* @param EOFitness & _fitness_eo2 the fitness of the second individual
* @param unsigned _iObj the index of the objective
*/
double epsilonValue (const EOFitness & _fitness_eo1,
const EOFitness & _fitness_eo2, const unsigned _iObj)
{
double result;
if (bounds[_iObj].range () == 0)
{
// min==max => every individuals has the same value for this objective
result = 0;
}
else
{
// computation of the epsilon value for the objective _iObj (in case of a minimization)
result =
(_fitness_eo1[_iObj] -
bounds[_iObj].minimum ()) / bounds[_iObj].range ();
result -=
(_fitness_eo2[_iObj] -
bounds[_iObj].minimum ()) / bounds[_iObj].range ();
// if we are maximizing, invert the value
if (traits::maximizing (_iObj))
result = -result;
}
// the espilon value
return result;
}
};
/**
* Functor
* Binary hypervolume indicator for eoParetoFitness
*/
template < class EOFitness > class eoBinaryHypervolumeIndicator:public eoBinaryQualityIndicator <
EOFitness >
{
public:
/**
* constructor
* @param double _rho reference point for the hypervolume calculation (rho must not be smaller than 1)
*/
eoBinaryHypervolumeIndicator (double _rho):eoBinaryQualityIndicator < EOFitness >
()
{
rho = _rho;
// consistency check
if (rho < 1)
{
cout <<
"Warning, reference point rho for the hypervolume calculation must not be smaller than 1"
<< endl;
cout << "Adjusted to 1" << endl;
rho = 1;
}
}
/**
* indicator value of the hypervolume of the portion of the objective space
* that is dominated by individual _eo1 but not by individual _eo2
* (don't forget to set the bounds before the call of this function)
* @param EOFitness & _fitness_eo1 the fitness of the first individual
* @param EOFitness & _fitness_eo2 the fitness of the second individual
*/
double operator () (const EOFitness & _fitness_eo1,
const EOFitness & _fitness_eo2)
{
double result;
if (_fitness_eo1.dominates (_fitness_eo2))
result =
-hypervolumeIndicatorValue (_fitness_eo1, _fitness_eo2,
traits::nObjectives ());
else
result =
hypervolumeIndicatorValue (_fitness_eo2, _fitness_eo1,
traits::nObjectives ());
return result;
}
private:
/** fitness traits */
typedef typename EOFitness::fitness_traits traits;
/** bounds */
using eoBinaryHypervolumeIndicator < EOFitness >::bounds;
/** reference point for the hypervolume calculation */
double rho;
/**
* computation of the hypervolume of the portion of the objective space
* that is dominated by individual _eo1 but not by individual _eo2
* @param EOFitness & _fitness_eo1 the fitness of the first individual
* @param EOFitness & _fitness_eo2 the fitness of the second individual
* @param unsigned _iObj number of objectives (used for iteration)
* @param bool _flag = false (only used for iteration)
*/
double hypervolumeIndicatorValue (const EOFitness & _fitness_eo1,
const EOFitness & _fitness_eo2,
const unsigned _iObj, const bool _flag =
false)
{
double result;
if (bounds[_iObj - 1].range () == 0)
{
// min==max => every individuals as the same value for this objective
result = 0;
}
else
{
if (traits::maximizing (_iObj - 1)) // maximizing
result =
hypervolumeIndicatorValueMax (_fitness_eo1, _fitness_eo2, _iObj,
_flag);
else // minimizing
result =
hypervolumeIndicatorValueMin (_fitness_eo1, _fitness_eo2, _iObj,
_flag);
}
return result;
}
/**
* computation of the hypervolume of the portion of the objective space
* that is dominated by individual _eo1 but not by individual _eo2
* in case of a minimization on the objective _iObj
* @param EOFitness & _fitness_eo1 the fitness of the first individual
* @param EOFitness & _fitness_eo2 the fitness of the second individual
* @param unsigned _iObj index of the objective
* @param bool _flag (only used for iteration)
*/
double hypervolumeIndicatorValueMin (const EOFitness & _fitness_eo1,
const EOFitness & _fitness_eo2,
const unsigned _iObj, const bool _flag)
{
double result;
double r = rho * bounds[_iObj - 1].range ();
double max = bounds[_iObj - 1].minimum () + r;
// fitness of individuals _eo1 and _eo2 for the objective _iObj (if flag==true, _eo2 is not taken into account)
double fitness_eo1 = _fitness_eo1[_iObj - 1];
double fitness_eo2;
if (_flag)
fitness_eo2 = max;
else
fitness_eo2 = _fitness_eo2[_iObj - 1];
// computation of the volume
if (_iObj == 1)
{
if (fitness_eo1 < fitness_eo2)
result = (fitness_eo2 - fitness_eo1) / r;
else
result = 0;
}
else
{
if (fitness_eo1 < fitness_eo2)
{
result =
hypervolumeIndicatorValue (_fitness_eo1, _fitness_eo2,
_iObj - 1) * (max - fitness_eo2) / r;
result +=
hypervolumeIndicatorValue (_fitness_eo1, _fitness_eo2,
_iObj - 1,
true) * (fitness_eo2 -
fitness_eo1) / r;
}
else
result =
hypervolumeIndicatorValue (_fitness_eo1, _fitness_eo2,
_iObj - 1) * (max - fitness_eo2) / r;
}
// the volume
return result;
}
/**
* computation of the hypervolume of the portion of the objective space
* that is dominated by individual _eo1 but not by individual _eo2
* in case of a maximization on the objective _iObj
* @param EOFitness & _fitness_eo1 the fitness of the first individual
* @param EOFitness & _fitness_eo2 the fitness of the second individual
* @param unsigned _iObj index of the objective
* @param bool _flag (only used for iteration)
*/
double hypervolumeIndicatorValueMax (const EOFitness & _fitness_eo1,
const EOFitness & _fitness_eo2,
const unsigned _iObj, const bool _flag)
{
double result;
double r = rho * bounds[_iObj - 1].range ();
double min = bounds[_iObj - 1].maximum () - r;
// fitness of individuals _eo1 and _eo2 for the objective _iObj (if flag==true, _eo2 is not taken into account)
double fitness_eo1 = _fitness_eo1[_iObj - 1];
double fitness_eo2;
if (_flag)
fitness_eo2 = min;
else
fitness_eo2 = _fitness_eo2[_iObj - 1];
// computation of the volume
if (_iObj == 1)
{
if (fitness_eo1 > fitness_eo2)
result = (fitness_eo1 - fitness_eo2) / r;
else
result = 0;
}
else
{
if (fitness_eo1 > fitness_eo2)
{
result =
hypervolumeIndicatorValue (_fitness_eo1, _fitness_eo2,
_iObj - 1) * (fitness_eo2 - min) / r;
result +=
hypervolumeIndicatorValue (_fitness_eo1, _fitness_eo2,
_iObj - 1,
true) * (fitness_eo1 -
fitness_eo2) / r;
}
else
result =
hypervolumeIndicatorValue (_fitness_eo1, _fitness_eo2,
_iObj - 1) * (fitness_eo2 - min) / r;
}
// the volume
return result;
}
};
#endif

View file

@ -0,0 +1,490 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
// "eoIBEA.h"
// (c) OPAC Team, LIFL, June 2006
/* This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: Arnaud.Liefooghe@lifl.fr
*/
#ifndef _eoIBEASorting_h
#define _eoIBEASorting_h
#include <math.h>
#include <list>
#include <eoPop.h>
#include <eoPerf2Worth.h>
#include "eoBinaryQualityIndicator.h"
/**
* Functor
* The sorting phase of IBEA (Indicator-Based Evolutionary Algorithm)
*/
template < class EOT, class Fitness > class eoIBEA:public eoPerf2WorthCached < EOT,
double >
{
public:
/** values */
using eoIBEA < EOT, Fitness >::value;
eoIBEA (eoBinaryQualityIndicator < Fitness > *_I)
{
I = _I;
}
/**
* mapping
* @param const eoPop<EOT>& _pop the population
*/
void calculate_worths (const eoPop < EOT > &_pop)
{
/* resizing the worths beforehand */
value ().resize (_pop.size ());
/* computation and setting of the bounds for each objective */
setBounds (_pop);
/* computation of the fitness for each individual */
fitnesses (_pop);
// higher is better, so invert the value
double max = *std::max_element (value ().begin (), value ().end ());
for (unsigned i = 0; i < value ().size (); i++)
value ()[i] = max - value ()[i];
}
protected:
/** binary quality indicator to use in the selection process */
eoBinaryQualityIndicator < Fitness > *I;
virtual void setBounds (const eoPop < EOT > &_pop) = 0;
virtual void fitnesses (const eoPop < EOT > &_pop) = 0;
};
/**
* Functor
* The sorting phase of IBEA (Indicator-Based Evolutionary Algorithm) without uncertainty
* Adapted from the Zitzler and Künzli paper "Indicator-Based Selection in Multiobjective Search" (2004)
* Of course, Fitness needs to be an eoParetoFitness object
*/
template < class EOT, class Fitness = typename EOT::Fitness > class eoIBEASorting:public eoIBEA < EOT,
Fitness
>
{
public:
/**
* constructor
* @param eoBinaryQualityIndicator<EOT>* _I the binary quality indicator to use in the selection process
* @param double _kappa scaling factor kappa
*/
eoIBEASorting (eoBinaryQualityIndicator < Fitness > *_I,
const double _kappa):
eoIBEA <
EOT,
Fitness > (_I)
{
kappa = _kappa;
}
private:
/** quality indicator */
using eoIBEASorting < EOT, Fitness >::I;
/** values */
using
eoIBEA <
EOT,
Fitness >::value;
/** scaling factor kappa */
double
kappa;
/**
* computation and setting of the bounds for each objective
* @param const eoPop<EOT>& _pop the population
*/
void
setBounds (const eoPop < EOT > &_pop)
{
typedef typename
EOT::Fitness::fitness_traits
traits;
double
min,
max;
for (unsigned i = 0; i < traits::nObjectives (); i++)
{
min = _pop[0].fitness ()[i];
max = _pop[0].fitness ()[i];
for (unsigned j = 1; j < _pop.size (); j++)
{
min = std::min (min, _pop[j].fitness ()[i]);
max = std::max (max, _pop[j].fitness ()[i]);
}
// setting of the bounds for the objective i
I->setBounds (i, min, max);
}
}
/**
* computation and setting of the fitness for each individual of the population
* @param const eoPop<EOT>& _pop the population
*/
void
fitnesses (const eoPop < EOT > &_pop)
{
// reprsentation of the fitness components
std::vector < std::vector < double > >
fitComponents (_pop.size (), _pop.size ());
// the maximum absolute indicator value
double
maxAbsoluteIndicatorValue = 0;
// computation of the indicator values and of the maximum absolute indicator value
for (unsigned i = 0; i < _pop.size (); i++)
for (unsigned j = 0; j < _pop.size (); j++)
if (i != j)
{
fitComponents[i][j] =
(*I) (_pop[i].fitness (), _pop[j].fitness ());
maxAbsoluteIndicatorValue =
std::max (maxAbsoluteIndicatorValue,
fabs (fitComponents[i][j]));
}
// computation of the fitness components for each pair of individuals
// if maxAbsoluteIndicatorValue==0, every individuals have the same fitness values for all objectives (already = 0)
if (maxAbsoluteIndicatorValue != 0)
for (unsigned i = 0; i < _pop.size (); i++)
for (unsigned j = 0; j < _pop.size (); j++)
if (i != j)
fitComponents[i][j] =
exp (-fitComponents[i][j] /
(maxAbsoluteIndicatorValue * kappa));
// computation of the fitness for each individual
for (unsigned i = 0; i < _pop.size (); i++)
{
value ()[i] = 0;
for (unsigned j = 0; j < _pop.size (); j++)
if (i != j)
value ()[i] += fitComponents[j][i];
}
}
};
/**
* Functor
* The sorting phase of IBEA (Indicator-Based Evolutionary Algorithm) under uncertainty
* Adapted from the Basseur and Zitzler paper "Handling Uncertainty in Indicator-Based Multiobjective Optimization" (2006)
* Of course, the fitness of an individual needs to be an eoStochasticParetoFitness object
*/
template < class EOT, class FitnessEval = typename EOT::Fitness::FitnessEval > class eoIBEAStochSorting:public eoIBEA < EOT,
FitnessEval
>
{
public:
/**
* constructor
* @param eoBinaryQualityIndicator<EOT>* _I the binary quality indicator to use in the selection process
*/
eoIBEAStochSorting (eoBinaryQualityIndicator < FitnessEval > *_I):eoIBEA < EOT,
FitnessEval >
(_I)
{
}
private:
/** quality indicator */
using eoIBEAStochSorting < EOT, FitnessEval >::I;
/** values */
using
eoIBEAStochSorting <
EOT,
FitnessEval >::value;
/**
* approximated zero value
*/
static double
zero ()
{
return 1e-7;
}
/**
* computation and setting of the bounds for each objective
* @param const eoPop<EOT>& _pop the population
*/
void
setBounds (const eoPop < EOT > &_pop)
{
typedef typename
EOT::Fitness::FitnessTraits
traits;
double
min,
max;
for (unsigned i = 0; i < traits::nObjectives (); i++)
{
min = _pop[0].fitness ().minimum (i);
max = _pop[0].fitness ().maximum (i);
for (unsigned j = 1; j < _pop.size (); j++)
{
min = std::min (min, _pop[j].fitness ().minimum (i));
max = std::max (max, _pop[j].fitness ().maximum (i));
}
// setting of the bounds for the ith objective
I->setBounds (i, min, max);
}
}
/**
* computation and setting of the fitness for each individual of the population
* @param const eoPop<EOT>& _pop the population
*/
void
fitnesses (const eoPop < EOT > &_pop)
{
typedef typename
EOT::Fitness::FitnessTraits
traits;
unsigned
nEval = traits::nEvaluations ();
unsigned
index;
double
eiv,
p,
sumP,
iValue;
std::list < std::pair < double, unsigned > > l;
std::vector < unsigned >
n (_pop.size ());
for (unsigned ind = 0; ind < _pop.size (); ind++)
{
value ()[ind] = 0.0; // fitness value for the individual ind
for (unsigned eval = 0; eval < nEval; eval++)
{
// I-values computation for the evaluation eval of the individual ind
l.clear ();
for (unsigned i = 0; i < _pop.size (); i++)
{
if (i != ind)
{
for (unsigned j = 0; j < nEval; j++)
{
std::pair < double, unsigned >
pa;
// I-value
pa.first =
(*I) (_pop[ind].fitness ()[eval],
_pop[i].fitness ()[j]);
// index of the individual
pa.second = i;
// append this to the list
l.push_back (pa);
}
}
}
// sorting of the I-values (in decreasing order)
l.sort ();
// computation of the Expected Indicator Value (eiv) for the evaluation eval of the individual ind
eiv = 0.0;
n.assign (n.size (), 0); // n[i]==0 for all i
sumP = 0.0;
while (((1 - sumP) > zero ()) && (l.size () > 0))
{
// we use the last element of the list (the greatest one)
iValue = l.back ().first;
index = l.back ().second;
// computation of the probability to appear
p = (1.0 / (nEval - n[index])) * (1.0 - sumP);
// eiv update
eiv += p * iValue;
// update of the number of elements for individual index
n[index]++;
// removing the last element of the list
l.pop_back ();
// sum of p update
sumP += p;
}
value ()[ind] += eiv / nEval;
}
}
}
};
/**
* Functor
* The sorting phase of IBEA (Indicator-Based Evolutionary Algorithm) under uncertainty using averaged values for each objective
* Follow the idea presented in the Deb & Gupta paper "Searching for Robust Pareto-Optimal Solutions in Multi-Objective Optimization", 2005
* Of course, the fitness of an individual needs to be an eoStochasticParetoFitness object
*/
template < class EOT, class FitnessEval = typename EOT::Fitness::FitnessEval > class eoIBEAAvgSorting:public eoIBEA < EOT,
FitnessEval
>
{
public:
/**
* constructor
* @param eoBinaryQualityIndicator<EOT>* _I the binary quality indicator to use in the selection process
* @param double _kappa scaling factor kappa
*/
eoIBEAAvgSorting (eoBinaryQualityIndicator < FitnessEval > *_I,
const double _kappa):
eoIBEA <
EOT,
FitnessEval > (_I)
{
kappa = _kappa;
}
private:
/** quality indicator */
using eoIBEAAvgSorting < EOT, FitnessEval >::I;
/** values */
using
eoIBEAAvgSorting <
EOT,
FitnessEval >::value;
/** scaling factor kappa */
double
kappa;
/**
* computation and setting of the bounds for each objective
* @param const eoPop<EOT>& _pop the population
*/
void
setBounds (const eoPop < EOT > &_pop)
{
typedef typename
EOT::Fitness::FitnessTraits
traits;
double
min,
max;
for (unsigned i = 0; i < traits::nObjectives (); i++)
{
min = _pop[0].fitness ().averagedParetoFitnessObject ()[i];
max = _pop[0].fitness ().averagedParetoFitnessObject ()[i];
for (unsigned j = 1; j < _pop.size (); j++)
{
min =
std::min (min,
_pop[j].fitness ().averagedParetoFitnessObject ()[i]);
max =
std::max (max,
_pop[j].fitness ().averagedParetoFitnessObject ()[i]);
}
// setting of the bounds for the objective i
I->setBounds (i, min, max);
}
}
/**
* computation and setting of the fitness for each individual of the population
* @param const eoPop<EOT>& _pop the population
*/
void
fitnesses (const eoPop < EOT > &_pop)
{
// reprsentation of the fitness components
std::vector < std::vector < double > >
fitComponents (_pop.size (), _pop.size ());
// the maximum absolute indicator value
double
maxAbsoluteIndicatorValue = 0;
// computation of the indicator values and of the maximum absolute indicator value
for (unsigned i = 0; i < _pop.size (); i++)
for (unsigned j = 0; j < _pop.size (); j++)
if (i != j)
{
fitComponents[i][j] =
(*I) (_pop[i].fitness ().averagedParetoFitnessObject (),
_pop[j].fitness ().averagedParetoFitnessObject ());
maxAbsoluteIndicatorValue =
std::max (maxAbsoluteIndicatorValue,
fabs (fitComponents[i][j]));
}
// computation of the fitness components for each pair of individuals
// if maxAbsoluteIndicatorValue==0, every individuals have the same fitness values for all objectives (already = 0)
if (maxAbsoluteIndicatorValue != 0)
for (unsigned i = 0; i < _pop.size (); i++)
for (unsigned j = 0; j < _pop.size (); j++)
if (i != j)
fitComponents[i][j] =
exp (-fitComponents[i][j] /
(maxAbsoluteIndicatorValue * kappa));
// computation of the fitness for each individual
for (unsigned i = 0; i < _pop.size (); i++)
{
value ()[i] = 0;
for (unsigned j = 0; j < _pop.size (); j++)
if (i != j)
value ()[i] += fitComponents[j][i];
}
}
};
#endif

View file

@ -0,0 +1,37 @@
#include<eoParetoFitness.h>
template < class EOT, class DistType > class eoParetoPhenDist
{
public:
virtual DistType operator ()(const EOT & eopf1, const EOT & eopf2) = 0;
};
//Euclidien distance
template < class EOT, class DistType =
double >class eoParetoEuclidDist:public eoParetoPhenDist < EOT, DistType >
{
public:
DistType operator () (const EOT & eopf1, const EOT & eopf2)
{
double res = 0.0;
double max = 0.0;
double temp;
for (unsigned i = 0; i < eopf1.fitness ().size (); ++i)
{
temp =
(eopf1.fitness ().operator[](i) -
eopf2.fitness ().operator[](i)) * (eopf1.fitness ().operator[](i) -
eopf2.fitness ().operator[](i));
if (temp > max)
max = temp; /* for normalization */
res = res + temp;
}
return sqrt (res / max);
}
};

View file

@ -0,0 +1,147 @@
// -*- C++ -*-
#include <EO.h>
#include <eoPerf2Worth.h>
#include <old/eoParetoPhenDist.h>
#include <eoParetoRanking.h>
template < class EOT, class worthT =
double >class eoParetoSharing:public eoPerf2Worth < EOT, worthT >
{
public:
eoParetoSharing (double _nicheSize):eoPerf2Worth < EOT,
worthT > ("ParetoSharing"), nicheSize (_nicheSize), dist (euc_dist),
Dmax (_nicheSize)
{
}
eoParetoSharing (double _nicheSize, eoParetoPhenDist < EOT,
worthT > &_dist):eoPerf2Worth < EOT,
worthT > ("ParetoSharing"), nicheSize (_nicheSize), dist (_dist),
Dmax (_nicheSize)
{
}
void operator () /*calculate_worths */ (const eoPop < EOT > &_pop)
{
unsigned i, j, pSize = _pop.size ();
//cout<<"**************************************************************************************\n";
// std :: cout << "psize = " << pSize << std :: endl ;
if (pSize <= 1)
throw std::
runtime_error ("Apptempt to do sharing with population of size 1");
eoPerf2Worth < EOT, worthT >::value ().resize (pSize);
std::vector < double >sim (pSize); // to hold the similarities
dMatrix distMatrix (pSize);
// compute the distance
distMatrix[0][0] = 0;
for (i = 1; i < pSize; i++)
{
distMatrix[i][i] = 0;
for (j = 0; j < i; j++)
{
//if
distMatrix[i][j] = distMatrix[j][i] = dist (_pop[i], _pop[j]);
//cout<<" "<<distMatrix[j][i]<<" "<<dist(_pop[i],_pop[j])<<"\n";
}
}
//compute the similarities
for (i = 0; i < pSize; i++)
{
double sum = 0.0;
for (j = 0; j < pSize; j++)
sum += sh (distMatrix[i][j], Dmax);
sim[i] = sum;
//cout<<"\n i ----->"<<sim[i]<<"\n";
}
eoDominanceMap < EOT > Dmap1;
Dmap1.setup (_pop);
eoParetoRanking < EOT > rnk1 (Dmap1);
rnk1.calculate_worths (_pop);
// now set the worthes values
for (i = 0; i < pSize; ++i)
{
typename EOT::Fitness v;
//cout<<"voila: "<<
//rnk1.value().operator[](i);
//vector<double> v;
//v.resize(_pop[i].fitness().size());
//for(unsigned k=0;k<_pop[i].fitness().size();++k)
//v[k]=_pop[i].fitness().operator[](k)/sim[i];
//_pop[i].fitness(v);//.operator[](k)=0;//_pop[i].fitness().operator[](k)/sim[i];
eoPerf2Worth < EOT, worthT >::value ()[i] = rnk1.value ().operator[](i) / sim[i]; //*_pop[i].fitness().operator[](1)*_pop[i].fitness().operator[](1));
//cout<<"\n__________"<<pSize<<" "<<value()[i]<<" "<<i;
}
}
class dMatrix:public std::vector < std::vector < double > >
{
public:
dMatrix (unsigned _s):rSize (_s)
{
this->resize (_s);
for (unsigned i = 0; i < _s; ++i)
this->operator[] (i).resize (_s);
}
void printOn (std::ostream & _os)
{
for (unsigned i = 0; i < rSize; i++)
for (unsigned j = 0; j < rSize; ++j)
{
_os << this->operator[](i)[j] << " ";
_os << endl;
}
_os << endl;
}
//public:
//std::vector<double>v;
private:
unsigned rSize;
};
private:
;
double sh (double dist, double Dmax)
{
if (dist < Dmax)
return (1.0 - dist / Dmax);
else
return (0.0);
}
double nicheSize;
eoParetoPhenDist < EOT, worthT > &dist;
eoParetoEuclidDist < EOT > euc_dist;
double Dmax;
};

View file

@ -0,0 +1,254 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
// "make_algo_MOEO.h"
// (c) OPAC Team, LIFL, June 2006
/* This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: Arnaud.Liefooghe@lifl.fr
*/
#ifndef _make_algo_MOEO_h
#define _make_algo_MOEO_h
// the parser and parameter includes
#include "utils/eoParser.h"
#include "utils/eoState.h"
// selections
#include "eoNDSorting.h"
#include "eoIBEA.h"
#include "eoBinaryQualityIndicator.h"
#include "eoParetoRanking.h"
#include "eoParetoSharing.h"
#include "eoSelectFromWorth.h"
#include "moeoSelectOneFromPopAndArch.h"
// replacements
#include "eoReplacement.h"
#include "moeoReplacement.h"
// breeders
#include "eoGeneralBreeder.h"
// the algorithm
#include "eoEasyEA.h"
/*
* This function builds the algorithm (i.e. selection and replacement) from existing continue (or checkpoint) and operators
* It uses a parser (to get user parameters) and a state (to store the memory)
*
* NB: this function is almost cut-and-pasted from EO/make_algo_pareto.h and integrates MOEO features
*/
template < class EOT >
eoAlgo < EOT > &do_make_algo_MOEO (eoParser & _parser, eoState & _state,
eoEvalFunc < EOT > &_eval,
eoContinue < EOT > &_continue,
eoGenOp < EOT > &_op,
moeoArchive < EOT > &_arch)
{
// the fitness of an EOT object
typedef typename EOT::Fitness EOFitness;
/* the selection criteria */
string & selStr = _parser.createParam (string ("NSGA-II"), "selCrit",
"Multi-objective selection criterion: NSGA, NSGA-II, IBEA, ParetoRanking, ParetoSharing",
'S', "Evolution Engine").value ();
double nicheSize = _parser.createParam (1.0, "nicheSize",
"Size of niche for NSGA-I or ParetoSharing",
'n',
"Evolution Engine").value ();
double kappa =
_parser.createParam (0.05, "kappa", "Scaling factor kappa for IBEA", 'k',
"Evolution Engine").value ();
string & indStr =
_parser.createParam (string ("Epsilon"), "indicator",
"Binary quality indicator for IBEA : Epsilon, Hypervolume",
'I', "Evolution Engine").value ();
double rho = _parser.createParam (1.1, "rho",
"reference point for the hypervolume calculation (must not be smaller than 1)",
'r', "Evolution Engine").value ();
// the eoPerf2Worth object
eoPerf2Worth < EOT, double >*p2w;
if ((selStr == string ("NSGA")) || (selStr == string ("NSGA-I"))) // NSGA-I
p2w = new eoNDSorting_I < EOT > (nicheSize);
else if (selStr == string ("NSGA-II")) // NSGA-II
p2w = new eoNDSorting_II < EOT > ();
/*
else if (selStr == string("IBEA")) { // IBEA
// the binary quality indicator
eoBinaryQualityIndicator<EOFitness>* I;
if (indStr == string("Epsilon"))
I = new eoAdditiveBinaryEpsilonIndicator<EOFitness>;
else if (indStr == string("Hypervolume"))
I = new eoBinaryHypervolumeIndicator<EOFitness>(rho);
else {
string stmp = string("Invalid binary quality indicator (for IBEA): ") + indStr;
throw std::runtime_error(stmp.c_str());
}
p2w = new eoIBEASorting<EOT>(I, kappa);
}
*/
else if (selStr == string ("ParetoRanking"))
{ // Pareto Ranking
eoDominanceMap < EOT > &dominance =
_state.storeFunctor (new eoDominanceMap < EOT >);
p2w = new eoParetoRanking < EOT > (dominance);
}
else if (selStr == string ("ParetoSharing"))
{ // Pareto Sharing
p2w = new eoParetoSharing < EOT > (nicheSize);
}
else
{
string stmp = string ("Invalid Pareto selection criterion: ") + selStr;
throw std::runtime_error (stmp.c_str ());
}
// store
_state.storeFunctor (p2w);
/* the selector */
eoValueParam < eoParamParamType > &selectionParam =
_parser.createParam (eoParamParamType ("DetTour(2)"), "selection",
"Selection: Roulette, DetTour(T), StochTour(t) or Random",
's', "Evolution Engine");
eoParamParamType & ppSelect = selectionParam.value (); // pair< string , vector<string> >
// the select object
eoSelectOne < EOT > *select;
if (ppSelect.first == string ("DetTour"))
{ // DetTour
unsigned detSize;
if (!ppSelect.second.size ())
{ // no parameter added
cerr << "WARNING, no parameter passed to DetTour, using 2" << endl;
detSize = 2;
// put back 2 in parameter for consistency (and status file)
ppSelect.second.push_back (string ("2"));
}
else // parameter passed by user as DetTour(T)
detSize = atoi (ppSelect.second[0].c_str ());
select = new eoDetTournamentWorthSelect < EOT > (*p2w, detSize);
}
else if (ppSelect.first == string ("StochTour"))
{ // StochTour
double p;
if (!ppSelect.second.size ())
{ // no parameter added
cerr << "WARNING, no parameter passed to StochTour, using 1" <<
endl;
p = 1;
// put back p in parameter for consistency (and status file)
ppSelect.second.push_back (string ("1"));
}
else // parameter passed by user as DetTour(T)
p = atof (ppSelect.second[0].c_str ());
select = new eoStochTournamentWorthSelect < EOT > (*p2w, p);
}
else if (ppSelect.first == string ("Roulette"))
{ // Roulette
select = new eoRouletteWorthSelect < EOT > (*p2w);
}
else if (ppSelect.first == string ("Random"))
{ // Random
select = new eoRandomSelect < EOT >;
}
else
{
string stmp = string ("Invalid selection: ") + ppSelect.first;
throw std::runtime_error (stmp.c_str ());
}
// store
_state.storeFunctor (select);
/* elitism */
bool useElitism = _parser.createParam (false, "elitism",
"Use elitism in the selection process (individuals from the archive are randomly selected)",
'E', "Evolution Engine").value ();
double ratioFromPop = _parser.createParam (0.8, "ratio",
"Ratio from the population for elitism (must not be greater than 1)",
'\0',
"Evolution Engine").value ();
if (useElitism)
{
eoSelectOne < EOT > *selectPop = select;
select =
new moeoSelectOneFromPopAndArch < EOT > (*selectPop, _arch,
ratioFromPop);
// store
_state.storeFunctor (select);
}
/* the number of offspring */
eoValueParam < eoHowMany > &offspringRateParam =
_parser.createParam (eoHowMany (1.0), "nbOffspring",
"Nb of offspring (percentage or absolute)", 'O',
"Evolution Engine");
/* the replacement */
string & repStr =
_parser.createParam (string ("Plus"), "replacement",
"Replacement: Plus, DistinctPlus or Generational",
'R', "Evolution Engine").value ();
eoReplacement < EOT > *replace;
if (repStr == string ("Plus")) // Plus
replace = new moeoElitistReplacement < EOT, double >(*p2w);
else if (repStr == string ("DistinctPlus")) // DistinctPlus
replace = new moeoDisctinctElitistReplacement < EOT, double >(*p2w);
else if (repStr == string ("Generational")) // Generational
replace = new eoGenerationalReplacement < EOT >;
else
{
string stmp = string ("Invalid replacement: ") + repStr;
throw std::runtime_error (stmp.c_str ());
}
// store
_state.storeFunctor (replace);
// the general breeder
eoGeneralBreeder < EOT > *breed =
new eoGeneralBreeder < EOT > (*select, _op, offspringRateParam.value ());
_state.storeFunctor (breed);
// the eoEasyEA
eoAlgo < EOT > *algo =
new eoEasyEA < EOT > (_continue, _eval, *breed, *replace);
_state.storeFunctor (algo);
// that's it!
return *algo;
}
#endif