// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; c++-electric-colon 1; c-auto-newline 1 -*- // GENVAR.CC : implementation of genVar-class functions #include // header file for this one... #include "genvar.hpp" const unsigned LENGTH_0 = 1, SIZE_0 = 2; // ------------------------------------------------------------- void genVar::initSize( unsigned _sizeAllele ) { // -- Checks and asigns size and related vars // ------------------------------------------------------------- if (!_sizeAllele) { cerr << "Alleles of zero length\n"; exit( SIZE_0 ); } size = _sizeAllele; maxForSize = (unsigned long) pow(MAX8BITS, size); } // --------------------------------------------------------------------- genVar::genVar( unsigned _numAlleles, unsigned _sizeAllele ) :rawGene( _numAlleles*_sizeAllele ) { // -- usual initial population constructor, or for tests // --------------------------------------------------------------------- initSize( _sizeAllele ); } // ---------------------- Constructor with 2 parents ------------------- // -------------------------------------------------------------------- genVar::genVar( genVar & _genVar1, genVar & _genVar2, double _xOverRate, double _mutationRate, double _killRate, double _dupRate): rawGene( _genVar1, _genVar2, _xOverRate, _mutationRate ) { // -- Builds a genome by mutating genVar1, with given MutationRate, // and adding genomes according to the proportions // --------------------------------------------------------------------- initSize( _genVar1.getSize() ); unsigned auxL = _genVar1.getLength(); // computes length unsigned auxL2 = _genVar2.getLength(); if ( auxL2 < auxL ) // take smaller one auxL = auxL2; if ( myrand(10000)/10000.0 < _dupRate) dupAllele( myrand( auxL ), _mutationRate ); if ( myrand(10000)/10000.0 < _killRate) killAllele( myrand( auxL ) ); } // -------------------------------------------------------------------- genVar::genVar( genVar & _genVar1, double _mutationRate, double _killRate, double _dupRate): rawGene( _genVar1, _mutationRate ){ // -- Builds a genVarome by mutating genVare1, with given MutationRate // --------------------------------------------------------------------- unsigned auxL = _genVar1.getLength(); // computes length initSize( _genVar1.getSize() ); if ( myrand(10000)/10000.0 < _dupRate) dupAllele( myrand( auxL ), _mutationRate ); if ( myrand(10000)/10000.0 < _killRate) killAllele( myrand( auxL ) ); } // -------------------------------------------------------------------- genVar::genVar( genVar& _genVar1, varLenOpMode _modeOp, unsigned _geneIdx, double _mutationRate ): rawGene( _genVar1, _mutationRate ) { // -- creates a new genome using one of 3 modes; using _geneIdx if // needed, _mutationRate is used only for duplication // --------------------------------------------------------------------- // all instance variables get initialized initSize( _genVar1.getSize() ); // now applies unary genetic operator as specified to the newly // created genome switch( _modeOp ) { case DUP : dupAllele( _geneIdx, _mutationRate ); break; case KILL : killAllele( _geneIdx ); break; case RANDINC : addAllele(); break; } } // --------------------------------------------------------------------- // getAllele- gets a string of size --size-- // --------------------------------------------------------------------- void genVar::getAllele( unsigned idx, char* _inStr ) const { memcpy( _inStr, getGenome() + idx*size, size ); } // --------------------------------------------------------------------- const char * genVar::getAllele( unsigned idx ) const { // getAllele- gets a string of size --size-- // --------------------------------------------------------------------- return getGenome() + idx*size; } // --------------------------------------------------------------------- void genVar::addAllele( ) { // -- adds another allele (size bytes) at the end of the string, of si // ze fixed by the instance variable // --------------------------------------------------------------------- addChunkEnd( size ); } // --------------------------------------------------------------------- void genVar::killAllele( unsigned _pos ){ // -- deletes an allele from position idx, redims string // --------------------------------------------------------------------- killChunk( size, _pos*size ); } // --------------------------------------------------------------------- void genVar::dupAllele( unsigned _pos, double _mutationRate ) { // -- duplicates the given allele with errors // --------------------------------------------------------------------- dupChunk( size, _pos*size ); for ( int i = 0; i < size*BITSINBYTE; i ++ ) // now alters a little bit the new gene if ( ( myrand(100)/100.0 ) < _mutationRate) changeBit( _pos*size*BITSINBYTE + i ); } // ----------------------------------------------------------------------- // Friendly operators // ------------------ // ----------------------------------------------------------------------- ostream& operator << ( ostream& s, const genVar & _inGen ) { // -- to print a genVar to stdout // ----------------------------------------------------------------------- for ( unsigned long i = 0; i < _inGen.getLength(); i ++ ) s << (int) (unsigned char) _inGen.getStr(i) << " "; return s; }