Perturb and acceptCrit added

git-svn-id: svn://scm.gforge.inria.fr/svnroot/paradiseo@1728 331e1502-861f-0410-8da2-ba01fb791d7f
This commit is contained in:
jhumeau 2010-03-30 09:59:08 +00:00
commit c2771d8a3a
10 changed files with 690 additions and 8 deletions

View file

@ -30,5 +30,34 @@ Contact: paradiseo-help@lists.gforge.inria.fr
#ifndef _moBetterAcceptCrit_h
#define _moBetterAcceptCrit_h
#include <acceptCrit/moAcceptanceCriterion.h>
#include <memory/moDummyMemory.h>
#include <comparator/moSolComparator.h>
/**
* Acceptance Criterion for extreme intensification : accept if the new solution is better than previous one
*/
template< class Neighbor >
class moBetterAcceptCrit : public moAcceptanceCriterion<Neighbor>, public moDummyMemory<Neighbor>{
public:
typedef typename Neighbor::EOT EOT;
moBetterAcceptCrit(moSolComparator<EOT>& _comparator):comparator(_comparator){}
/**
* Accept if the new solution is better than previous one
* @param _sol1 the previous solution
* @param _sol2 the new solution after local search
* @return true if the new solution is better than previous one
*/
bool operator()(EOT& _sol1, EOT& _sol2){
return comparator(_sol1, _sol2);
}
private:
moSolComparator<EOT>& comparator;
};
#endif

View file

@ -35,13 +35,9 @@
#ifndef _moNeighborComparator_h
#define _moNeighborComparator_h
#include <EO.h>
#include <eoFunctor.h>
#include <neighborhood/moNeighbor.h>
#include <comparator/moComparator.h>
/**
* Comparator of two neighbors
*/

View file

@ -0,0 +1,72 @@
/*
<moSolComparator.h>
Copyright (C) DOLPHIN Project-Team, INRIA Lille - Nord Europe, 2006-2010
Sébastien Verel, Arnaud Liefooghe, Jérémie Humeau
This software is governed by the CeCILL license under French law and
abiding by the rules of distribution of free software. You can ue,
modify and/ or redistribute the software under the terms of the CeCILL
license as circulated by CEA, CNRS and INRIA at the following URL
"http://www.cecill.info".
In this respect, the user's attention is drawn to the risks associated
with loading, using, modifying and/or developing or reproducing the
software by the user in light of its specific status of free software,
that may mean that it is complicated to manipulate, and that also
therefore means that it is reserved for developers and experienced
professionals having in-depth computer knowledge. Users are therefore
encouraged to load and test the software's suitability as regards their
requirements in conditions enabling the security of their systems and/or
data to be ensured and, more generally, to use and operate it in the
same conditions as regards security.
The fact that you are presently reading this means that you have had
knowledge of the CeCILL license and that you accept its terms.
ParadisEO WebSite : http://paradiseo.gforge.inria.fr
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef _moSolComparator_h
#define _moSolComparator_h
#include <comparator/moComparator.h>
/**
* Comparator of two solutions
*/
template< class EOT >
class moSolComparator : public moComparator<EOT, EOT>
{
public:
/**
* Compare two solutions
* @param _sol1 the first solution
* @param _sol2 the second solution
* @return true if the solution2 is better than solution1
*/
virtual bool operator()(const EOT& _sol1, const EOT& _sol2) {
return (_sol1.fitness() < _sol2.fitness());
}
/**
* Compare two solutions
* @param _sol1 the first solution
* @param _sol2 the second solution
* @return true if the solution2 is equal to solution1
*/
virtual bool equals(const EOT& _sol1, const EOT& _sol2) {
return (_sol1.fitness() == _sol2.fitness());
}
/**
* Return the class id.
* @return the class name as a std::string
*/
virtual std::string className() const {
return "moSolComparator";
}
};
#endif

View file

@ -0,0 +1,119 @@
/*
<moCountMoveMemory.h>
Copyright (C) DOLPHIN Project-Team, INRIA Lille - Nord Europe, 2006-2010
Sébastien Verel, Arnaud Liefooghe, Jérémie Humeau
This software is governed by the CeCILL license under French law and
abiding by the rules of distribution of free software. You can ue,
modify and/ or redistribute the software under the terms of the CeCILL
license as circulated by CEA, CNRS and INRIA at the following URL
"http://www.cecill.info".
In this respect, the user's attention is drawn to the risks associated
with loading, using, modifying and/or developing or reproducing the
software by the user in light of its specific status of free software,
that may mean that it is complicated to manipulate, and that also
therefore means that it is reserved for developers and experienced
professionals having in-depth computer knowledge. Users are therefore
encouraged to load and test the software's suitability as regards their
requirements in conditions enabling the security of their systems and/or
data to be ensured and, more generally, to use and operate it in the
same conditions as regards security.
The fact that you are presently reading this means that you have had
knowledge of the CeCILL license and that you accept its terms.
ParadisEO WebSite : http://paradiseo.gforge.inria.fr
Contact: paradiseo-help@lists.gforge.inria.fr
*/
#ifndef _moCountMoveMemory_h
#define _moCountMoveMemory_h
#include <memory/moMemory.h>
/**
* Count the number of move, noMove and the number of successive stagnation since the last Move
*/
template< class Neighbor >
class moCountMoveMemory : virtual public moMemory<Neighbor>{
public:
typedef typename Neighbor::EOT EOT;
/**
* Init all the counters
* @param _sol unused solution
*/
void init(EOT & _sol) {
nbMove=0;
nbNoMove=0;
counter=0;
}
/**
* @param _sol unused solution
* @param _neighbor unused neighbor
*/
void add(EOT & _sol, Neighbor & _neighbor) {
nbMove++;
counter=0;
}
/**
* @param _sol unused solution
* @param _neighbor unused neighbor
*/
void update(EOT & _sol, Neighbor & _neighbor) {
nbNoMove++;
counter++;
}
/**
* ClearMemory : Reinit all the counters
*/
void clearMemory() {
nbMove=0;
nbNoMove=0;
counter=0;
}
/**
* Getter of the number of move
* @return the counter
*/
unsigned int getNbMove(){
return nbMove;
}
/**
* Getter of the number of no move
* @return the counter
*/
unsigned int getNbNoMove(){
return nbNoMove;
}
/**
* Getter of the number of successive stagnation since the last Move
* @return the counter
*/
unsigned int getCounter(){
return counter;
}
/**
* Init counter
*/
void initCounter(){
counter=0;
}
private:
unsigned int nbMove;
unsigned int nbNoMove;
unsigned int counter;
};
#endif

View file

@ -40,6 +40,7 @@
#include <comparator/moComparator.h>
#include <comparator/moNeighborComparator.h>
#include <comparator/moSolNeighborComparator.h>
#include <comparator/moSolComparator.h>
#include <continuator/moCheckpoint.h>
#include <continuator/moContinuator.h>
@ -86,6 +87,7 @@
#include <memory/moMemory.h>
#include <memory/moSolVectorTabuList.h>
#include <memory/moTabuList.h>
#include <memory/moCountMoveMemory.h>
#include <neighborhood/moBackableNeighbor.h>
#include <neighborhood/moBitNeighbor.h>
@ -100,9 +102,12 @@
#include <perturb/moPerturbation.h>
#include <perturb/moMonOpPerturb.h>
#include <perturb/moRestartPerturb.h>
#include <perturb/moNeighborhoodPerturb.h>
#include <acceptCrit/moAcceptanceCriterion.h>
#include <acceptCrit/moAlwaysAcceptCrit.h>
#include <acceptCrit/moBetterAcceptCrit.h>
#include <coolingSchedule/moCoolingSchedule.h>
#include <coolingSchedule/moSimpleCoolingSchedule.h>

View file

@ -47,6 +47,7 @@ public:
/**
* Default Constructor
* @param _monOp an eoMonOp (pertubation operator)
* @param _fullEval a full evaluation function
*/
moMonOpPerturb(eoMonOp<EOT>& _monOp, eoEvalFunc<EOT>& _fullEval):monOp(_monOp), fullEval(_fullEval){}

View file

@ -30,5 +30,79 @@ Contact: paradiseo-help@lists.gforge.inria.fr
#ifndef _moNeighborhoodPerturb_h
#define _moNeighborhoodPerturb_h
#include <eval/moEval.h>
#include <perturb/moPerturbation.h>
/**
* Neighborhood Perturbation: explore the neighborhood to perturb the solution (the neighborhood could be different as the one used in the Local Search)
*/
template< class Neighbor, class OtherNH >
class moNeighborhoodPerturb : public moPerturbation<Neighbor>{
public:
typedef typename Neighbor::EOT EOT;
typedef typename OtherNH::Neighbor OtherN;
/**
* Default Constructor
* @param _otherNeighborhood a neighborhood
* @param _eval an Evaluation Function
*/
moNeighborhoodPerturb(OtherNH& _otherNeighborhood, moEval<OtherN>& _eval): otherNeighborhood(_otherNeighborhood), eval(_eval){}
/**
* Apply move on the solution
* @param _solution the current solution
* @return true
*/
virtual bool operator()(EOT& _solution){
if(otherNeighborhood.hasNeighbor(_solution)){
eval(_solution, current);
current.move(_solution);
_solution.fitness(current.fitness());
}
return true;
}
/**
* Init the neighborhood
* @param _sol the current solution
*/
virtual void init(EOT & _sol){
if(otherNeighborhood.hasNeighbor(_sol))
otherNeighborhood.init(_sol, current);
}
/**
* ReInit the neighborhood because a move was done
* @param _sol the current solution
* @param _neighbor unused neighbor (always empty)
*/
virtual void add(EOT & _sol, Neighbor & _neighbor){
(*this).init(_sol);
}
/**
* Explore another neighbor because no move was done
* @param _sol the current solution
* @param _neighbor unused neighbor (always empty)
*/
virtual void update(EOT & _sol, Neighbor & _neighbor){
if(otherNeighborhood.cont(_sol))
otherNeighborhood.next(_sol, current);
else
(*this).init(_sol);
}
/**
* NOTHING TO DO
*/
virtual void clearMemory(){}
private:
OtherNH& otherNeighborhood;
moEval<OtherN>& eval;
OtherN current;
};
#endif

View file

@ -31,4 +31,47 @@ Contact: paradiseo-help@lists.gforge.inria.fr
#define _moRestartPerturb_h
#include <eoEvalFunc.h>
#include <eoInit.h>
#include <perturb/moPerturbation.h>
#include <memory/moCountMoveMemory.h>
/**
* Restart Perturbation : restart when maximum number of iteration with no improvement is reached
*/
template< class Neighbor >
class moRestartPerturb : public moPerturbation<Neighbor>, public moCountMoveMemory<Neighbor> {
public:
typedef typename Neighbor::EOT EOT;
/**
* Default Constructor
* @param _init an initializer of solution
* @param _fullEval a full evaluation function
* @param _threshold maximum number of iteration with no improvement
*/
moRestartPerturb(eoInit<EOT>& _init, eoEvalFunc<EOT>& _fullEval, unsigned int _threshold):init(_init), fullEval(_fullEval), threshold(_threshold) {}
/**
* Apply restart when necessary
* @param _solution to restart
* @return true
*/
bool operator()(EOT& _solution){
if((*this).getCounter()>= threshold){
init(_solution);
fullEval(_solution);
(*this).initCounter();
}
return true;
}
private:
eoInit<EOT>& init;
eoEvalFunc<EOT>& fullEval;
unsigned int threshold;
};
#endif

View file

@ -25,8 +25,10 @@ using namespace std;
//-----------------------------------------------------------------------------
// fitness function
#include <funcOneMax.h>
#include <funcNK.h>
#include <eoInt.h>
#include <neighborhood/moOrderNeighborhood.h>
#include <neighborhood/moRndWithoutReplNeighborhood.h>
#include <oneMaxBitNeighbor.h>
#include <eval/moFullEvalByModif.h>
@ -39,14 +41,18 @@ using namespace std;
#include <explorer/moILSexplorer.h>
#include <perturb/moMonOpPerturb.h>
#include <perturb/moRestartPerturb.h>
#include <perturb/moNeighborhoodPerturb.h>
#include <acceptCrit/moAlwaysAcceptCrit.h>
#include <acceptCrit/moBetterAcceptCrit.h>
#include <continuator/moIterContinuator.h>
// REPRESENTATION
//-----------------------------------------------------------------------------
typedef eoBit<unsigned> Indi;
typedef eoBit<unsigned int> Indi;
typedef moBitNeighbor<unsigned int> Neighbor ; // incremental evaluation
typedef moOrderNeighborhood<Neighbor> Neighborhood ;
typedef moRndWithoutReplNeighborhood<Neighbor> Neighborhood2 ;
typedef moSimpleHCexplorer<Neighborhood> NHE;
void main_function(int argc, char **argv)
@ -107,6 +113,7 @@ void main_function(int argc, char **argv)
FuncOneMax<Indi> eval(vecSize);
//FuncNK<Indi> eval(vecSize, 2);
/* =========================================================
*
@ -148,6 +155,7 @@ void main_function(int argc, char **argv)
* ========================================================= */
Neighborhood neighborhood(vecSize);
Neighborhood2 neighborhood2(vecSize);
/* =========================================================
@ -171,13 +179,20 @@ void main_function(int argc, char **argv)
eoBitMutation<Indi> monOp(1.0/vecSize);
moMonOpPerturb<Neighbor> perturb(monOp, eval);
//moMonOpPerturb<Neighbor> perturb(monOp, eval);
moAlwaysAcceptCrit<Neighbor> accept;
//moRestartPerturb<Neighbor> perturb(random, eval, 5);
moNeighborhoodPerturb<Neighbor, Neighborhood2> perturb(neighborhood2, fulleval);
moSolComparator<Indi> comp;
//moAlwaysAcceptCrit<Neighbor> accept;
moBetterAcceptCrit<Neighbor> accept(comp);
moILSexplorer< NHE > explorerILS(hc, perturb, accept);
moIterContinuator<Neighborhood> continuatorILS(10);
moIterContinuator<Neighborhood> continuatorILS(100);
moLocalSearch< moILSexplorer< moSimpleHCexplorer<Neighborhood> > >localSearch(explorerILS, continuatorILS, eval);

View file

@ -0,0 +1,328 @@
#ifndef __funcNK
#define __funcNK
#include <eo>
#include <fstream>
#include <vector>
using namespace std;
template< class EOT >
class FuncNK : public eoEvalFunc<EOT> {
public:
// tables des contributions
double ** tables;
// liste des liens epistatiques en fonction du bit i
// pour chaque contribution, donne la liste des variables consernés
unsigned ** links;
// liste inverse
// pour chaque variable, donne la liste indices des contributions
vector<unsigned> * knils;
unsigned N;
unsigned K;
// constructeur vide
FuncNK() : N(0), K(0)
{
tables = NULL;
links = NULL;
};
FuncNK(unsigned _n) : N(_n), K(0)
{
tables = NULL;
links = NULL;
};
// construction de tables aléatoirement
FuncNK(int n, int k, bool consecutive = false) : N(n), K(k)
{
if (consecutive)
consecutiveTables();
else
randomTables();
};
// construction à partir d'un fichier des tables et des liens
FuncNK(const char * fichier = "")
{
load(fichier);
};
~FuncNK()
{
deleteTables();
};
void buildTables()
{
links = new unsigned*[N];
knils = new vector<unsigned>[N];
tables = new double*[N];
for(unsigned i = 0; i < N; i++) {
tables[i] = new double[1<<(K+1)];
links[i] = new unsigned[K+1];
knils[i].clear();
}
};
void deleteTables()
{
if (links != NULL) {
for(int i = 0; i < N; i++) {
delete [] (links[i]);
}
delete [] links;
links = NULL;
}
if (knils != NULL) {
/*
for(int i = 0; i < N; i++) {
knils[i].clear();
}
*/
delete [] knils;
knils = NULL;
}
if (tables != NULL) {
for(int i = 0; i < N; i++) {
delete [] (tables[i]);
}
delete [] tables;
tables = NULL;
}
};
virtual void load(const char * nomTables)
{
fstream file;
file.open(nomTables, ios::in);
if (file.is_open()) {
//cout <<"loadTables: chargement des tables " <<nomTables <<endl;
string s;
// lecture des commentaires
string line;
file >> s;
while (s[0] == 'c') {
getline(file,line,'\n');
file >> s;
}
// lecture des parametres
if (s[0] != 'p') {
cerr <<"loadTables: erreur de lecture de paramètre pour " << nomTables <<endl;
exit(1);
}
file >> s;
if (s != "NK") {
cerr <<"erreur " <<nomTables << " n'est pas un fichier NK" <<endl;
exit(1);
}
// lecture des paramètres N et K
file >> N >> K;
buildTables();
// lecture des liens
if (s[0] != 'p') {
cerr <<"loadTables: erreur de lecture de paramètre 'links' pour " << nomTables <<endl;
exit(1);
}
file >> s;
if (s == "links") {
loadLinks(file);
} else {
cerr <<"loadTables: erreur de lecture de paramètre 'links' pour " << nomTables <<endl;
exit(1);
}
// lecture des tables
if (s[0] != 'p') {
cerr <<"loadTables: erreur de lecture de paramètre 'tables' pour " << nomTables <<endl;
exit(1);
}
file >> s;
if (s == "tables") {
loadTables(file);
} else {
cerr << "loadTables: erreur de lecture de paramètre 'tables' pour " << nomTables <<endl;
exit(1);
}
file.close();
} else {
cerr << "loadTables: impossible d'ouvrir " << nomTables << endl;
}
};
void loadLinks(fstream & file) {
for(int j = 0; j < K+1; j++)
for(int i = 0; i < N; i++) {
file >> links[i][j];
knils[links[i][j]].push_back(i);
}
}
void loadTables(fstream & file) {
for(int j = 0; j < (1<<(K+1)); j++)
for(int i = 0; i < N; i++)
file >> tables[i][j];
}
virtual void save(const char * nomTables)
{
// cout <<"saveTables: sauvegarde de la table " <<nomTables <<endl;
fstream file;
file.open(nomTables, ios::out);
if (file.is_open()) {
file << "c name of file : " << nomTables << endl;
file << "p NK " << N << " " << K <<endl;
file << "p links" << endl;
for(int j=0; j<K+1; j++)
for(int i=0; i<N; i++)
file << links[i][j] << endl;
file << "p tables" << endl;
for(int j=0; j<(1<<(K+1)); j++) {
for(int i=0; i<N; i++)
file << tables[i][j] << " ";
file << endl;
}
file.close();
} else {
cerr <<"saveTables: impossible d'ouvrir " <<nomTables <<endl;
}
};
void affiche()
{
int j;
for(int i=0; i<N; i++) {
cout <<"link " <<i <<" : ";
for(j = 0; j <= K; j++)
cout <<links[i][j] <<" ";
cout <<endl;
}
cout <<endl;
for(int i=0; i<N; i++) {
cout <<"knils " <<i <<" : ";
for(j=0; j<knils[i].size(); j++)
cout <<knils[i][j] <<" ";
cout <<endl;
}
cout <<endl;
for(int i=0; i<N; i++) {
cout <<"table " <<i <<endl;
for(j=0; j<(1<<(K+1)); j++)
cout << tables[i][j] <<endl;
}
};
// calcul de la fitness
virtual void operator() (EOT & genome)
{
double accu = 0.0;
for(int i = 0; i < N; i++)
accu += tables[i][sigma(genome,i)];
// double M = 0.05;
// genome.fitness( M * ((unsigned) (accu / (N*M))) ); // affecte la fitness du genome
genome.fitness( accu / (double) N ); // affecte la fitness du genome
};
protected:
void initTirage(int tabTirage[]) {
for(int i = 0; i<N; i++)
tabTirage[i] = i;
};
void perm(int tabTirage[],int i, int j) {
int k = tabTirage[i];
tabTirage[i] = tabTirage[j];
tabTirage[j] = k;
};
void tire(int i,int tabTirage[]) {
int t[K+1];
for(int j=0; j<K+1; j++) {
if (j==0) t[j]=i;
else t[j] = rng.random(N-j);
links[i][j] = tabTirage[t[j]];
knils[tabTirage[t[j]]].push_back(i);
perm(tabTirage, t[j], N-1-j);
}
for(int j=K; j>=0; j--)
perm(tabTirage, t[j], N-1-j);
};
void consecutiveLinks(int i) {
for(int j=0; j<K+1; j++) {
links[i][j] = (i + j) % N;
knils[(i + j) % N].push_back(i);
}
};
// tables et liens aléatoires
virtual void randomTables() {
buildTables();
int tabTirage[N];
initTirage(tabTirage);
for(int i = 0; i < N; i++) {
// construit les loci epistatiquement liés au locus i
tire(i, tabTirage);
// la table Fi
for(int j = 0; j < (1<<(K+1)); j++)
tables[i][j] = rng.uniform();
}
};
// tables et liens aléatoires
virtual void consecutiveTables() {
buildTables();
for(int i = 0; i < N; i++) {
// construit les loci epistatiquement liés au locus i
consecutiveLinks(i);
// la table Fi
for(int j = 0; j < (1<<(K+1)); j++)
tables[i][j] = rng.uniform();
}
};
// extrait les bits liés au bit n°i
unsigned int sigma(EOT & genome, int i)
{
unsigned int n = 1;
unsigned int accu = 0;
for(int j=0; j<K+1; j++) {
if (genome[links[i][j]] == 1)
accu = accu | n;
n = n<<1;
}
return accu;
};
};
#endif