#include "genetic/phenotypebinary.h" #include #include using namespace Bu; // Bits per word #define BPW (sizeof(uint_fast32_t)*8) #define wordsForBits( x ) (((x)/BPW)+(((x)%BPW)?1:0)) #define wordWithBit( x ) ((x)/BPW) Genetic::PhenotypeBinary::PhenotypeBinary( int iSize, bool bRandom ) : iSize( iSize ), iWords( wordsForBits(iSize) ), aGenes( NULL ) { aGenes = new uint_fast32_t[iWords]; if( bRandom ) randomize(); } Genetic::PhenotypeBinary::~PhenotypeBinary() { delete[] aGenes; } Genetic::Phenotype &Genetic::PhenotypeBinary::randomize() { for( int j = 0; j < iWords*sizeof(uint_fast32_t); j++ ) { ((uint8_t *)aGenes)[j] = (uint8_t)Bu::Random::rand(); } return *this; } void Genetic::PhenotypeBinary::mutate( int iLocation, float fMagnitude ) { if( fMagnitude > -0.5 && fMagnitude < 0.5 ) return; aGenes[wordWithBit(iLocation)] = (aGenes[wordWithBit(iLocation)]&(~(1<<((iLocation)%BPW)))) | ((~aGenes[wordWithBit(iLocation)])&((1<<((iLocation)%BPW)))); } Genetic::Phenotype *Genetic::PhenotypeBinary::makeEmptyOffspring( int iNewSize ) { if( iNewSize < 0 ) iNewSize = iSize; return new PhenotypeBinary( iSize ); } Genetic::Phenotype &Genetic::PhenotypeBinary::copyFrom( const Phenotype &rSrc, int iStart, int iCount, int iDest ) { const PhenotypeBinary &rbSrc = dynamic_cast(rSrc); if( iDest < 0 ) iDest = iStart; // Fist draft, very sloppy: bit by bit copy, this is stupid, but easy for( int j = 0; j < iCount; j++ ) { int wd = wordWithBit(j+iDest); int ws = wordWithBit(j+iStart); if( (rbSrc.aGenes[ws]&(1<<((j+iStart)%BPW))) == 0) { aGenes[wd] &= ~(1<<((j+iDest)%BPW)); } else { aGenes[wd] |= (1<<((j+iDest)%BPW)); } } /* iStart%BPW int iWords = wordsForBits(iCount); for( int j = wordWithBit(iStart); j < iWords; j++ ) { } */ return *this; } Bu::String Genetic::PhenotypeBinary::toString() { Bu::String sRet; for( int j = 0; j < iSize; j++ ) { sRet += (aGenes[j/BPW]&(1<<(j%BPW)))?'1':'0'; } return sRet; } void Genetic::PhenotypeBinary::extractBits( uint32_t &rTarget, int iStart, int iBits ) { rTarget = 0; if( iBits > sizeof(rTarget)*8 ) iBits = sizeof(rTarget)*8; // This is pretty much the same problem as copyFrom, so I'm doing it the // same way for now. for( int j = 0; j < iBits; j++ ) { int ws = wordWithBit(j+iStart); if( (aGenes[ws]&(1<<((j+iStart)%BPW))) != 0 ) rTarget |= (1<<(j%BPW)); } } void Genetic::PhenotypeBinary::extractBits( uint64_t &rTarget, int iStart, int iBits ) { rTarget = 0; if( iBits > sizeof(rTarget)*8 ) iBits = sizeof(rTarget)*8; // This is pretty much the same problem as copyFrom, so I'm doing it the // same way for now. for( int j = 0; j < iBits; j++ ) { int ws = wordWithBit(j+iStart); if( (aGenes[ws]&(1<<((j+iStart)%BPW))) != 0 ) rTarget |= (1ll<<(j)); } } void Genetic::PhenotypeBinary::write( Bu::Stream &rStream ) { rStream.write( aGenes, sizeof(uint_fast32_t)*iWords ); } void Genetic::PhenotypeBinary::read( Bu::Stream &rStream ) { rStream.read( aGenes, sizeof(uint_fast32_t)*iWords ); }