fix eoDetSingdeBitFlip: better algorithm
The old version was inefficient, using trial and errors. This new version is a single pass algorithm.
This commit is contained in:
parent
934b368ed0
commit
75c2c6ab76
1 changed files with 29 additions and 26 deletions
|
|
@ -99,18 +99,19 @@ template<class Chrom> class eoDetBitFlip: public eoMonOp<Chrom>
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** eoDetSingleBitFlip --> changes exactly k bits with checking for duplicate
|
/** Changes exactly k bits with checking for duplicate
|
||||||
\class eoDetSingleBitFlip eoBitOp.h ga/eoBitOp.h
|
|
||||||
\ingroup bitstring
|
\ingroup bitstring
|
||||||
*/
|
*/
|
||||||
|
template<class Chrom>
|
||||||
template<class Chrom> class eoDetSingleBitFlip: public eoMonOp<Chrom>
|
class eoDetSingleBitFlip: public eoMonOp<Chrom>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* (Default) Constructor.
|
* (Default) Constructor.
|
||||||
* @param _num_bit The number of bits to change
|
* @param _num_bit The number of bits to change
|
||||||
* default is one - equivalent to eoOneBitFlip then
|
* default is one - equivalent to eoOneBitFlip then
|
||||||
|
*
|
||||||
|
* @note: use a reference for num_bit, thus you may change and recall without having to re-instantiate.
|
||||||
*/
|
*/
|
||||||
eoDetSingleBitFlip(const unsigned& _num_bit = 1): num_bit(_num_bit) {}
|
eoDetSingleBitFlip(const unsigned& _num_bit = 1): num_bit(_num_bit) {}
|
||||||
|
|
||||||
|
|
@ -122,32 +123,34 @@ template<class Chrom> class eoDetSingleBitFlip: public eoMonOp<Chrom>
|
||||||
* @param chrom The cromosome which one bit is going to be changed.
|
* @param chrom The cromosome which one bit is going to be changed.
|
||||||
*/
|
*/
|
||||||
bool operator()(Chrom& chrom)
|
bool operator()(Chrom& chrom)
|
||||||
{
|
{
|
||||||
std::vector< unsigned > selected;
|
// All possible indices
|
||||||
|
std::vector< unsigned > indices;
|
||||||
|
indices.reserve(chrom.size());
|
||||||
|
for(unsigned i=0; i<chrom.size(); ++i) {
|
||||||
|
indices.push_back(i);
|
||||||
|
}
|
||||||
|
|
||||||
// check for duplicate
|
// Shuffle indices
|
||||||
for (unsigned k=0; k<num_bit; k++)
|
for(unsigned i=0; i<indices.size(); ++i) {
|
||||||
{
|
unsigned other = eo::rng.random(indices.size());
|
||||||
unsigned temp;
|
std::swap(indices[i], indices[other]);
|
||||||
|
}
|
||||||
|
|
||||||
do
|
// Flip at first indices
|
||||||
{
|
for(unsigned i=0; i<num_bit; ++i) {
|
||||||
temp = eo::rng.random( chrom.size() );
|
chrom[indices[i]] = !chrom[indices[i]];
|
||||||
}
|
}
|
||||||
while ( find( selected.begin(), selected.end(), temp ) != selected.end() );
|
|
||||||
|
|
||||||
selected.push_back(temp);
|
if(num_bit > 0) {
|
||||||
}
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for ( size_t i = 0; i < selected.size(); ++i )
|
protected:
|
||||||
{
|
const unsigned& num_bit;
|
||||||
chrom[i] = !chrom[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
unsigned num_bit;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue