A lot a small change to improve the things, and new moBitsWithReplNeighborhhod

git-svn-id: svn://scm.gforge.inria.fr/svnroot/paradiseo@2564 331e1502-861f-0410-8da2-ba01fb791d7f
This commit is contained in:
verel 2011-12-14 22:02:54 +00:00
commit 4b51948118
9 changed files with 470 additions and 175 deletions

View file

@ -90,6 +90,14 @@ public:
explorer(_neighborhood, _eval, _compN, _compSN)
{}
/**
* Return the class id.
* @return the class name as a std::string
*/
virtual std::string className() const {
return "moFirstImprHV";
}
private:
// always true continuator
moTrueContinuator<Neighbor> trueCont;

View file

@ -78,8 +78,6 @@ public:
// initialization of the external continuator (for example the time, or the number of generations)
cont->init(_solution);
std::cout << _solution.fitness() << std::endl;
bool b;
do {
// explore the neighborhood of the solution
@ -91,8 +89,6 @@ public:
} else
searchExplorer.moveApplied(false);
std::cout << _solution.fitness() << std::endl;
// update the parameter of the search (for ex. Temperature of the SA)
searchExplorer.updateParam(_solution);

View file

@ -104,11 +104,12 @@ public:
}
} else {
if (searchExplorer->moveApplied()) { // compute the new fitness only when the solution has moved
// the currentNeighbor is the previous neighbor
if (searchExplorer->moveApplied()) {
// compute the new fitness only when the solution has moved
// the selectedNeighbor is the neighbor which is selected in the neighborhood
// the movement is made on this neighbor
// we suppose that the neighborhood is bit string neighborhood (indexed neighbor)
unsigned iMove = searchExplorer->getCurrentNeighbor().index();
unsigned iMove = searchExplorer->getSelectedNeighbor().index();
for(unsigned i = 0; i < n; i++) {
if (i == iMove)
@ -149,56 +150,6 @@ public:
}
private:
/**
* compute the delta of fitness in linear time (incremental evaluation)
*
* @param i the neighbor to consider
*/
/*
void fullDelta(unsigned int i) {
unsigned int j;
int d = Q[i][i];
for(j = 0; j < i; j++)
if (current[j])
d += Q[i][j];
for(j = i+1; j < n; j++)
if (current[j])
d += Q[j][i];
if (current[i])
d = - d;
delta[i] = d;
}
*/
/**
* compute the delta of delta in constant time (3 tests and 1 operation)
*
* @param i the neighbor to consider
*/
/*
void updateDelta(unsigned int i) {
if (i == iMove)
delta[i] = - delta[i] ;
else {
if (current[i] != current[iMove])
if (i < iMove)
delta[i] += Q[iMove][i];
else
delta[i] += Q[i][iMove];
else
if (i < iMove)
delta[i] -= Q[iMove][i];
else
delta[i] -= Q[i][iMove];
}
}
*/
// number of variables
int n;

View file

@ -58,7 +58,7 @@ public:
*/
moVNSexplorer(moVariableNeighborhoodSelection<EOT> & _selection,
moAcceptanceCriterion<Neighbor>& _acceptCrit):
moNeighborhoodExplorer<Neighbor>(), selection(_selection), acceptCrit(_acceptCrit), stop(false)
moNeighborhoodExplorer<Neighbor>(), selection(_selection), acceptCrit(_acceptCrit), stop(false), first(true)
{}
/**
@ -72,7 +72,12 @@ public:
* @param _solution the current solution
*/
virtual void initParam(EOT& _solution) {
// the best solution found
bestSoFar = _solution;
// initialization of the LS
selection.init(_solution);
// for the first ls, the solution will be improved, so the next ls must be applied
first = true;
}
/**
@ -80,7 +85,8 @@ public:
* @param _solution the current solution
*/
virtual void updateParam(EOT & _solution) {
if ((*this).moveApplied()) {
if (!first && (*this).moveApplied()) {
first = false;
selection.init(_solution);
} else
if (selection.cont(currentSol)) {
@ -90,9 +96,11 @@ public:
}
/**
* terminate: NOTHING TO DO
* terminate: return the best solution found
*/
virtual void terminate(EOT & _solution) {};
virtual void terminate(EOT & _solution) {
_solution = bestSoFar;
}
/**
* Explore the neighborhood of a solution by the "neighborhood" search heuristics
@ -105,6 +113,10 @@ public:
currentSol = _solution;
shake(currentSol);
ls(currentSol);
// update the best solution found
if (bestSoFar.fitness() < currentSol.fitness())
bestSoFar = currentSol;
}
/**
@ -142,10 +154,18 @@ public:
}
private:
/** the set of LS and shake operators to applied */
moVariableNeighborhoodSelection<EOT>& selection;
/** Acceptance criterium between two LS */
moAcceptanceCriterion<Neighbor>& acceptCrit;
/** stopping criterium flag */
bool stop;
/** the current solution */
EOT currentSol;
/** Best solution found during the search */
EOT bestSoFar;
/** first LS flag */
bool first;
};

View file

@ -60,6 +60,7 @@
#include <comparator/moEqualNeighborComparator.h>
#include <comparator/moEqualSolNeighborComparator.h>
#include <comparator/moSolComparator.h>
#include <comparator/moEqualSolComparator.h>
#include <comparator/moSolNeighborComparator.h>
#include <continuator/moAverageFitnessNeighborStat.h>
@ -177,6 +178,7 @@
#include <problems/bitString/moBitsNeighbor.h>
#include <problems/bitString/moBitsNeighborhood.h>
#include <problems/bitString/moBitsWithoutReplNeighborhood.h>
#include <problems/bitString/moBitsWithReplNeighborhood.h>
// #include <problems/bitString/moPopBitNeighbor.h>
// #include <problems/bitString/moPopBitsNeighbor.h>

View file

@ -58,99 +58,50 @@ public:
* Constructor
* @param _length bit string length
* @param _nBits maximum number of bits to flip (radius of the neighborhood)
* @param _exactDistance when true, only neighbor with exactly k bits flip are considered, other neighbor <= Hamming distance k
*/
moBitsNeighborhood(unsigned _length, unsigned _nBits): moNeighborhood<Neighbor>(), length(_length), nBits(_nBits) {
int j;
bool last;
neighborhoodSize = 0;
for(int d = 1; d <= nBits; d++) {
vector<unsigned int> bits(d);
// the first one for this Hamming distance
for(unsigned i = 0; i < d; i++)
bits[i] = i;
neighborsVec.push_back(bits);
// the others ones
last = false;
while(!last) {
j = d - 1;
if (bits[j] < length - 1) {
bits[j]++;
neighborsVec.push_back(bits);
} else {
j--;
while ( (j >= 0) && (bits[j] + 1 == bits[j+1]) )
j--;
if (j < 0) {
last = true;
} else {
bits[j]++;
for(unsigned i = j+1; i < d; i++)
bits[i] = bits[i-1] + 1;
neighborsVec.push_back(bits);
}
}
}
moBitsNeighborhood(unsigned _length, unsigned _nBits, bool _exactDistance = false): moNeighborhood<Neighbor>(), length(_length), nBits(_nBits) {
// neighborhood size :
// for distance == nBits : length \choose nBits = length! / ( (length - nBits)! * nBits!)
// for distance <= nBits : sum of previous distances
if (_exactDistance) {
neighborhoodSize = numberOfNeighbors(nBits);
} else {
neighborhoodSize = 0;
for(int d = 1; d <= nBits; d++)
neighborhoodSize += numberOfNeighbors(d);
}
neighborhoodSize = neighborsVec.size();
}
/**
* Number fo neighbors at Hamming distance d
*
* @param d Hamming distance
*/
unsigned int numberOfNeighbors(unsigned d) {
unsigned int fact_nBits = 1;
for(unsigned k = 1; k <= d; k++)
fact_nBits *= k;
unsigned int fact_length = 1;
for(unsigned k = length; k > length - d; k--)
fact_length *= k;
return fact_length / fact_nBits;
}
/**
* Test if it exist a neighbor
* @param _solution the solution to explore
* @return true if the neighborhood was not empty: the population size is at least 1
* @return true if the neighborhood was not empty (bit string larger than 0)
*/
virtual bool hasNeighbor(EOT& _solution) {
return _solution.size() > 0;
}
/**
* Initialization of the neighborhood:
* apply several bit flips on the solution
* @param _solution the solution to explore
* @param _neighbor the first neighbor
*/
virtual void init(EOT & _solution, Neighbor & _neighbor) {
key = 0;
_neighbor.bits.resize(nBits);
setNeighbor(0, _neighbor);
}
/**
* Give the next neighbor
* apply several bit flips on the solution
* @param _solution the solution to explore (population of solutions)
* @param _neighbor the next neighbor which in order of distance
*/
virtual void next(EOT & _solution, Neighbor & _neighbor) {
key++;
setNeighbor(key, _neighbor);
}
/**
* Test if all neighbors are explored or not,if false, there is no neighbor left to explore
* @param _solution the solution to explore
* @return true if there is again a neighbor to explore: population size larger or equals than 1
*/
virtual bool cont(EOT & _solution) {
return key < neighborhoodSize - 1;
}
/**
* Return the class Name
* @return the class name as a std::string
@ -159,10 +110,6 @@ public:
return "moBitsNeighborhood";
}
unsigned int index() {
return key;
}
protected:
// length of the bit strings
unsigned int length;
@ -173,25 +120,6 @@ protected:
// size of the neighborhood
unsigned int neighborhoodSize;
// list of neighbors
vector< vector<unsigned int> > neighborsVec;
// key of the neighbor which is currently explored
unsigned int key;
/**
* Set the neighbor to the correct neighbor
* @param _key index in neighborVec of the neighbor to set
* @param _neighbor neighbor to set
*/
virtual void setNeighbor(unsigned _key, Neighbor & _neighbor) {
_neighbor.nBits = neighborsVec[_key].size();
for(unsigned i = 0; i < _neighbor.nBits; i++)
_neighbor.bits[i] = neighborsVec[_key][i];
}
};
#endif

View file

@ -0,0 +1,199 @@
/*
<moBitsWithReplNeighborhood.h>
Copyright (C) DOLPHIN Project-Team, INRIA Lille - Nord Europe, 2006-2010
Sebastien Verel, Arnaud Liefooghe, Jeremie Humeau
This software is governed by the CeCILL license under French law and
abiding by the rules of distribution of free software. You can use,
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".
As a counterpart to the access to the source code and rights to copy,
modify and redistribute granted by the license, users are provided only
with a limited warranty and the software's author, the holder of the
economic rights, and the successive licensors have only limited liability.
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 _moBitsWithReplNeighborhood_h
#define _moBitsWithReplNeighborhood_h
#include <neighborhood/moNeighborhood.h>
#include <problems/bitString/moBitsNeighborhood.h>
#include <utils/eoRNG.h>
#include <vector>
/**
* A neighborhood for bit string solutions
* where several bits could be flipped
* under a given Hamming distance
*
* The neighborhood is explored in a random order
* Each neighbors is visited once time
* and the number of visited neighbors is a parameter
*/
template< class Neighbor >
class moBitsWithReplNeighborhood : public moBitsNeighborhood<Neighbor>
{
using moBitsNeighborhood<Neighbor>::neighborhoodSize;
using moBitsNeighborhood<Neighbor>::length;
using moBitsNeighborhood<Neighbor>::nBits;
using moBitsNeighborhood<Neighbor>::numberOfNeighbors;
public:
/**
* Define type of a solution corresponding to Neighbor
*/
typedef typename Neighbor::EOT EOT;
/**
* Constructor
*
* @param _length bit string length
* @param _nBits maximum number of bits to flip (radius of the neighborhood)
* @param _sampleSize number of neighbor to sample in the neighborhood, if 0 all the neighborhood is sampled
* @param _exactDistance when true, only neighbor with exactly k bits flip are considered, other neighbor <= Hamming distance k
*/
moBitsWithReplNeighborhood(unsigned _length, unsigned _nBits, unsigned _sampleSize, bool _exactDistance = false): moBitsNeighborhood<Neighbor>(_length, _nBits, _exactDistance), sampleSize(_sampleSize), exactDistance(_exactDistance) {
if (sampleSize > neighborhoodSize || sampleSize == 0)
sampleSize = neighborhoodSize;
indexVector.resize(length);
for(unsigned int i = 0; i < length; i++)
indexVector[i] = i;
if (!exactDistance) {
nSize.resize(nBits);
nSize[0] = numberOfNeighbors(1);
for(unsigned d = 2; d <= nBits; d++)
nSize[d - 1] = nSize[d - 2] + numberOfNeighbors(d);
}
nNeighbors = 0;
}
/**
* one random neighbor at Hamming distance _n
*
* @param _solution the solution to explore
* @param _neighbor the first neighbor
* @param _n Hamming distance of the neighbor
*/
virtual void randomNeighbor(EOT & _solution, Neighbor & _neighbor, unsigned _n) {
_neighbor.bits.resize(_n);
_neighbor.nBits = _n;
unsigned i;
unsigned b;
unsigned tmp;
for(unsigned k = 0; k < _n; k++) {
i = rng.random(length - k);
b = indexVector[i];
_neighbor.bits[k] = b;
indexVector[i] = indexVector[length - k - 1];
indexVector[length - k - 1] = b;
}
}
/**
* one random neighbor at maximal Hamming distance _n
*
* @param _solution the solution to explore
* @param _neighbor the first neighbor
*/
virtual void randomNeighbor(EOT & _solution, Neighbor & _neighbor) {
if (exactDistance)
randomNeighbor(_solution, _neighbor, nBits);
else {
// equiprobability between neighbors at maximal Hamming distance nBits
unsigned n = rng.random(neighborhoodSize);
unsigned d = 1;
while (n < nSize[d - 1]) d++;
randomNeighbor(_solution, _neighbor, d);
}
}
/**
* Initialization of the neighborhood:
* one random neighbor
*
* @param _solution the solution to explore
* @param _neighbor the first neighbor
*/
virtual void init(EOT & _solution, Neighbor & _neighbor) {
randomNeighbor(_solution, _neighbor);
nNeighbors = 1;
}
/**
* Give the next neighbor
* apply several bit flips on the solution
* @param _solution the solution to explore (population of solutions)
* @param _neighbor the next neighbor which in order of distance
*/
virtual void next(EOT & _solution, Neighbor & _neighbor) {
randomNeighbor(_solution, _neighbor);
nNeighbors++;
}
/**
* Test if all neighbors are explored or not,if false, there is no neighbor left to explore
* @param _solution the solution to explore
* @return true if there is again a neighbor to explore: population size larger or equals than 1
*/
virtual bool cont(EOT & _solution) {
return nNeighbors < sampleSize ;
}
/**
* Return the class Name
* @return the class name as a std::string
*/
virtual std::string className() const {
return "moBitsWithReplNeighborhood";
}
protected:
// vector of possible bits
std::vector<unsigned int> indexVector;
// maximum number of visited neighbor i.e. number of neighbor to sample in the neighborhood
unsigned int sampleSize;
// number of visited neighbors
unsigned nNeighbors;
// when true, only neighbors at Hamming distance nBits
bool exactDistance;
// the number of neighbors below the given distance
std::vector<unsigned int> nSize;
};
#endif

View file

@ -45,15 +45,15 @@
* where several bits could be flipped
* under a given Hamming distance
*
* The neighborhood is explred in a random order
* and the number of neighbors is fixed by a number
* The neighborhood is explored in a random order
* Each neighbors is visited once time
* and the number of visited neighbors is a parameter
*/
template< class Neighbor >
class moBitsWithoutReplNeighborhood : public moBitsNeighborhood<Neighbor>
{
using moBitsNeighborhood<Neighbor>::neighborhoodSize;
using moBitsNeighborhood<Neighbor>::setNeighbor;
using moBitsNeighborhood<Neighbor>::key;
using moBitsNeighborhood<Neighbor>::length;
using moBitsNeighborhood<Neighbor>::nBits;
public:
@ -67,9 +67,10 @@ public:
* Constructor
* @param _length bit string length
* @param _nBits maximum number of bits to flip (radius of the neighborhood)
* @param _sampleSize number of neighbor to sample in the neighborhood
* @param _sampleSize number of neighbor to sample in the neighborhood, if 0 all the neighborhood is sampled
* @param _exactDistance when true, only neighbor with exactly k bits flip are considered, other neighbor <= Hamming distance k
*/
moBitsWithoutReplNeighborhood(unsigned _length, unsigned _nBits, unsigned _sampleSize): moBitsNeighborhood<Neighbor>(_length, _nBits), sampleSize(_sampleSize) {
moBitsWithoutReplNeighborhood(unsigned _length, unsigned _nBits, unsigned _sampleSize, bool _exactDistance = false): moBitsNeighborhood<Neighbor>(_length, _nBits, _exactDistance), sampleSize(_sampleSize) {
if (sampleSize > neighborhoodSize || sampleSize == 0)
sampleSize = neighborhoodSize;
@ -77,17 +78,64 @@ public:
for(unsigned int i = 0; i < neighborhoodSize; i++)
indexVector[i] = i;
/* all the neighbors */
if (neighborhoodSize >= 1000000) {
std::cout << "moBitsNeighborhood::Warning : the neighborhood size is larger than 10^6 : " << neighborhoodSize << std::endl;
}
int j;
bool last;
unsigned firstIndex;
if (_exactDistance)
firstIndex = nBits;
else
firstIndex = 1;
for(int d = firstIndex; d <= nBits; d++) {
vector<unsigned int> bits(d);
// the first one for this Hamming distance
for(unsigned i = 0; i < d; i++)
bits[i] = i;
neighborsVec.push_back(bits);
// the others ones
last = false;
while(!last) {
j = d - 1;
if (bits[j] < length - 1) {
bits[j]++;
neighborsVec.push_back(bits);
} else {
j--;
while ( (j >= 0) && (bits[j] + 1 == bits[j+1]) )
j--;
if (j < 0) {
last = true;
} else {
bits[j]++;
for(unsigned i = j+1; i < d; i++)
bits[i] = bits[i-1] + 1;
neighborsVec.push_back(bits);
}
}
}
}
if (neighborhoodSize != neighborsVec.size())
std::cout << "moBitsNeighborhood::Warning -> error in the neighborhood size computation, please check... : " << neighborhoodSize << " / " << neighborsVec.size() << std::endl;
}
/**
* Test if it exist a neighbor
* @param _solution the solution to explore
* @return true if the neighborhood was not empty: the population size is at least 1
*/
virtual bool hasNeighbor(EOT& _solution) {
return _solution.size() > 0;
}
/**
* Initialization of the neighborhood:
* apply several bit flips on the solution
@ -157,6 +205,25 @@ protected:
// maximum number of visited neighbor i.e. number of neighbor to sample in the neighborhood
unsigned int sampleSize;
// list of neighbors
vector< vector<unsigned int> > neighborsVec;
// key of the neighbor which is currently explored
unsigned int key;
/**
* Set the neighbor to the correct neighbor
* @param _key index in neighborVec of the neighbor to set
* @param _neighbor neighbor to set
*/
virtual void setNeighbor(unsigned _key, Neighbor & _neighbor) {
_neighbor.nBits = neighborsVec[_key].size();
for(unsigned i = 0; i < _neighbor.nBits; i++)
_neighbor.bits[i] = neighborsVec[_key][i];
}
};
#endif

View file

@ -0,0 +1,124 @@
/*
<moUBQPBitsIncrEval.h>
Copyright (C) DOLPHIN Project-Team, INRIA Lille - Nord Europe, 2006-2010
Sebastien Verel, Arnaud Liefooghe, Jeremie 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 _moUBQPBitsIncrEval_H
#define _moUBQPBitsIncrEval_H
#include <eval/moEval.h>
#include <eval/ubqpEval.h>
/**
* Incremental evaluation Function for the UBQPSimple problem
* when several bits are flipped (moBitsNeighbor)
*/
template< class Neighbor >
class moUBQPBitsIncrEval : public moEval<Neighbor>
{
public:
typedef typename Neighbor::EOT EOT;
/*
* default constructor
* @param _ubqpEval full evaluation of the UBQP problem
*/
moUBQPBitsIncrEval(UbqpEval<EOT> & _ubqpEval) {
n = _ubqpEval.getNbVar();
Q = _ubqpEval.getQ();
}
/*
* Incremental evaluation of the neighbor for the UBQP problem (complexity O(n * k) when k bits are flipped)
* @param _solution the solution to move (bit string)
* @param _neighbor the neighbor to consider of type moBitsNeighbor (several bits are flipped)
*/
virtual void operator()(EOT & _solution, Neighbor & _neighbor) {
unsigned int b;
unsigned int j;
int d, delta;
delta = 0;
for(unsigned i = 0; i < _neighbor.nBits; i++) {
b = _neighbor.bits[i];
d = Q[b][b];
for(j = 0; j < b; j++)
if (_solution[j] == 1)
d += Q[b][j];
for(j = b+1; j < n; j++)
if (_solution[j] == 1)
d += Q[j][b];
if (_solution[b] == 0)
delta += d;
else
delta -= d;
// move the solution on this bit
_solution[b] = !_solution[b];
}
// move back the solution
for(unsigned i = 0; i < _neighbor.nBits; i++) {
b = _neighbor.bits[i];
_solution[b] = !_solution[b];
}
_neighbor.fitness(_solution.fitness() + delta);
}
/*
* to get the matrix Q
*
* @return matrix Q
*/
int** getQ() {
return Q;
}
/*
* to get the number of variable (bit string length)
*
* @return bit string length
*/
int getNbVar() {
return n;
}
private:
// number of variables
int n;
// matrix Q (supposed to be in lower triangular form)
int ** Q;
};
#endif