Example #1
0
// This is a an implementation of a uniform crossover for the binary string.
// It assumes that the the genomes are all the same length.
int
BitStringGenome::UniformCrossover(const GAGenome& a, const GAGenome& b, 
				  GAGenome* c, GAGenome* d) {
  BitStringGenome& mom=(BitStringGenome &)a;
  BitStringGenome& dad=(BitStringGenome &)b;

  int n = 0;

  if(c && d){
    BitStringGenome& sis=(BitStringGenome &)*c;
    BitStringGenome& bro=(BitStringGenome &)*d;
    for(int i=sis.length()-1; i>=0; i--){
      if(GARandomBit()){
	sis.gene(i, mom.gene(i));
	bro.gene(i, dad.gene(i));
      }
      else{
	sis.gene(i, dad.gene(i));
	bro.gene(i, mom.gene(i));
      }
    }
    n = 2;
  }
  else {
    BitStringGenome& sis = (c ? (BitStringGenome&)*c : (BitStringGenome&)*d);
    for(int i=sis.length()-1; i>=0; i--)
      sis.gene(i, (GARandomBit() ? mom.gene(i) : dad.gene(i)));
    n = 1;
  }

  return n;
}
Example #2
0
int
GA2DBinaryStringGenome::resize(int w, int h)
{
  if((unsigned int)w == nx && (unsigned int)h == ny) return sz;

  if(w == GAGenome::ANY_SIZE)
    w = GARandomInt(minX, maxX);
  else if(w < 0)
    w = nx;		// do nothing
  else if(minX == maxX)
    minX=maxX = w;
  else{
    if(w < STA_CAST(int, minX)) w=minX;
    if(w > STA_CAST(int, maxX)) w=maxX;
  }

  if(h == GAGenome::ANY_SIZE)
    h = GARandomInt(minY, maxY);
  else if(h < 0)
    h = ny;		// do nothing
  else if(minY == maxY)
    minY=maxY = h;
  else{
    if(h < STA_CAST(int, minY)) h=minY;
    if(h > STA_CAST(int, maxY)) h=maxY;
  }

// Move the bits into the right position.  If we're smaller, then shift to
// the smaller size before we do the resize (the resize method maintains bit
// integrety).  If we're larger, do the move after the resize.  If we're the 
// same size the we don't do anything.  When we're adding more bits, the new
// bits get set randomly to 0 or 1.

  if(w < STA_CAST(int,nx)){
    int y=GAMin(STA_CAST(int,ny),h);
    for(int j=0; j<y; j++)
      GABinaryString::move(j*w,j*nx,w);
  }
  GABinaryString::resize(w*h);
  if(w > STA_CAST(int,nx)){		// adjust the existing chunks of bits
    int y=GAMin(STA_CAST(int,ny),h);
    for(int j=y-1; j>=0; j--){
      GABinaryString::move(j*w,j*nx,nx);
      for(int i=nx; i<w; i++)
	bit(j*w+i, GARandomBit());
    }
  }
  if(h > STA_CAST(int,ny)){		// change in height is always new bits
    for(int i=w*ny; i<w*h; i++)
      bit(i, GARandomBit());
  }

  nx = w; ny = h;
  _evaluated = gaFalse;
  return sz;
}
Example #3
0
/* ----------------------------------------------------------------------------
3D Binary String Genome
  The order for looping through indices is depth-then-height-then-width
(ie depth loops before a single height increment, height loops before a single
width increment)
---------------------------------------------------------------------------- */
void 
GA3DBinaryStringGenome::UniformInitializer(GAGenome & c)
{
  GA3DBinaryStringGenome &child=(GA3DBinaryStringGenome &)c;
  child.resize(GAGenome::ANY_SIZE,GAGenome::ANY_SIZE,GAGenome::ANY_SIZE);
  for(int i=child.width()-1; i>=0; i--)
    for(int j=child.height()-1; j>=0; j--)
      for(int k=child.depth()-1; k>=0; k--)
	child.gene(i,j,k, GARandomBit());
}
//   Resize the genome.  If someone specifies ANY_RESIZE then we pick a random
// size within the behaviour limits that have been set.  If limits have been
// set and someone passes us something outside the limits, we resize to the
// closest bound.  If the genome is fixed size (ie min limit equals max limit)
// then we resize to the specified value and move the min/max to match it.
int
GA1DBinaryStringGenome::resize(int l)
{
  if(l == STA_CAST(int, nx)) return nx;

  if(l == GAGenome::ANY_SIZE)
    l = GARandomInt(minX, maxX);
  else if(l < 0)
    return nx;			// do nothing
  else if(minX == maxX)
    minX=maxX=l;
  else{
    if(l < STA_CAST(int, minX)) l=minX;
    if(l > STA_CAST(int, maxX)) l=maxX;
  }

  GABinaryString::resize(l);
  if(l > STA_CAST(int, nx))
    for(int i=nx; i<l; i++)
      bit(i, GARandomBit());
  nx = l;
  _evaluated = gaFalse;
  return sz;
}
Example #5
0
//   Evolve a new generation of genomes.  A steady-state GA has no 'old'
// and 'new' populations - we pick from the current population and replace its
// members with the new ones we create.  We replace the worst members of the
// preceeding population.  If a genome in the tmp population is worse than
// one in the main population, the genome in the main population will be
// replaced regardless of its better score.
void
GASteadyStateGA::step()
{
  int i, mut, c1, c2;
  GAGenome *mom, *dad;          // tmp holders for selected genomes

// Generate the individuals in the temporary population from individuals in
// the main population.

  for(i=0; i<tmpPop->size()-1; i+=2){	// takes care of odd population
    mom = &(pop->select());
    dad = &(pop->select());
    stats.numsel += 2;		// keep track of number of selections

    c1 = c2 = 0;
    if(GAFlipCoin(pCrossover())){
      stats.numcro += (*scross)(*mom, *dad, &tmpPop->individual(i),
                &tmpPop->individual(i+1));
      c1 = c2 = 1;
    }
    else{
      tmpPop->individual( i ).copy(*mom);
      tmpPop->individual(i+1).copy(*dad);
    }
    stats.nummut += (mut = tmpPop->individual( i ).mutate(pMutation()));
    if(mut > 0) c1 = 1;
    stats.nummut += (mut = tmpPop->individual(i+1).mutate(pMutation()));
    if(mut > 0) c2 = 1;

    stats.numeval += c1 + c2;
  }
  if(tmpPop->size() % 2 != 0){	// do the remaining population member
    mom = &(pop->select());
    dad = &(pop->select());
    stats.numsel += 2;		// keep track of number of selections

    c1 = 0;
    if(GAFlipCoin(pCrossover())){
      stats.numcro += (*scross)(*mom, *dad,
                &tmpPop->individual(i), (GAGenome*)0);
      c1 = 1;
    }
    else{
      if(GARandomBit())
    tmpPop->individual( i ).copy(*mom);
      else
    tmpPop->individual( i ).copy(*dad);
    }
    stats.nummut += (mut = tmpPop->individual( i ).mutate(pMutation()));
    if(mut > 0) c1 = 1;

    stats.numeval += c1;
  }

// Replace the worst genomes in the main population with all of the individuals
// we just created.  Notice that we invoke the population's add member with a
// genome pointer rather than reference.  This way we don't force a clone of
// the genome - we just let the population take over.  Then we take it back by
// doing a remove then a replace in the tmp population.

  for(i=0; i<tmpPop->size(); i++)
    pop->add(&tmpPop->individual(i));
  pop->evaluate();		// get info about current pop for next time
  pop->scale();			// remind the population to do its scaling

// the individuals in tmpPop are all owned by pop, but tmpPop does not know
// that.  so we use replace to take the individuals from the pop and stick
// them back into tmpPop
  for(i=0; i<tmpPop->size(); i++)
    tmpPop->replace(pop->remove(GAPopulation::WORST, GAPopulation::SCALED), i);

  stats.numrep += tmpPop->size();

  stats.update(*pop);		// update the statistics by one generation
}
Example #6
0
//   Evolve a new generation of genomes.  A steady-state GA has no 'old'
// and 'new' populations - we pick from the current population and replace its
// members with the new ones we create.  We generate either one or two children
// each 'generation'.  The replacement strategy is set by the GA.
void
GAIncrementalGA::step()
{
  int mut, c1, c2;
  GAGenome *mom, *dad;          // tmp holders for selected genomes

  mom = &(pop->select());
  dad = &(pop->select());
  stats.numsel += 2;		// keep track of the number of selections

  if(noffspr == 1){
    c1 = 0;
    if(GAFlipCoin(pCrossover())){
      stats.numcro += (*scross)(*mom, *dad, child1, (GAGenome*)0);
      c1 = 1;
    }
    else{
      if(GARandomBit())
    child1->copy(*mom);
      else
    child1->copy(*dad);
    }
    stats.nummut += (mut = child1->mutate(pMutation()));
    if(mut > 0) c1 = 1;

    stats.numeval += c1;

    if(rs == PARENT)
      child1 = pop->replace(child1, mom);
    else if(rs == CUSTOM)
      child1 = pop->replace(child1, &(rf(*child1, *pop)));
    else
      child1 = pop->replace(child1, rs);

    stats.numrep += 1;
  }
  else{
    c1 = c2 = 0;
    if(GAFlipCoin(pCrossover())){
      stats.numcro += (*scross)(*mom, *dad, child1, child2);
      c1 = c2 = 1;
    }
    else{
      child1->copy(*mom);
      child2->copy(*dad);
    }
    stats.nummut += (mut = child1->mutate(pMutation()));
    if(mut > 0) c1 = 1;
    stats.nummut += (mut = child2->mutate(pMutation()));
    if(mut > 0) c2 = 1;

    stats.numeval += c1 + c2;

    if(rs == PARENT){
      child1 = pop->replace(child1, mom);
      if(mom == dad)		// this is a possibility, if so do worst
    child2 = pop->replace(child2, GAPopulation::WORST);
      else
    child2 = pop->replace(child2, dad);
    }
    else if(rs == CUSTOM){
      child1 = pop->replace(child1, &(rf(*child1, *pop)));
      child2 = pop->replace(child2, &(rf(*child2, *pop)));
    }
    else{
      child1 = pop->replace(child1, rs);
      child2 = pop->replace(child2, rs);
    }

    stats.numrep += 2;
  }

  pop->evaluate(gaTrue);        // allow pop-based evaluators to do their thing
  stats.update(*pop);		// update the statistics for this generation
}
Example #7
0
// The random initializer sets the bits in the bit string randomly to 0 or 1.
// It uses the GARandomBit function to do this (GARandomBit is pretty efficient
// in terms of its calls to your system's random function).
void 
BitStringGenome::UniformInitializer(GAGenome & c) {
  BitStringGenome &genome=(BitStringGenome &)c;
  for(int i=genome.length()-1; i>=0; i--)
    genome.gene(i, GARandomBit());
}
Example #8
0
//   Evolve a new generation of genomes.  When we start this routine, pop
// contains the current generation.  When we finish, pop contains the new 
// generation and oldPop contains the (no longer) current generation.  The 
// previous old generation is lost.  We don't deallocate any memory, we just
// reset the contents of the genomes.
//   The selection routine must return a pointer to a genome from the old
// population.
void
GASimpleGA::step()
{
  int i, mut, c1, c2;
  GAGenome *mom, *dad;          // tmp holders for selected genomes

  GAPopulation *tmppop;		// Swap the old population with the new pop.
  tmppop = oldPop;		// When we finish the ++ we want the newly 
  oldPop = pop;			// generated population to be current (for
  pop = tmppop;			// references to it from member functions).

// Generate the individuals in the temporary population from individuals in 
// the main population.

  for(i=0; i<pop->size()-1; i+=2){	// takes care of odd population
    mom = &(oldPop->select());  
    dad = &(oldPop->select());
    stats.numsel += 2;		// keep track of number of selections

    c1 = c2 = 0;
    if(GAFlipCoin(pCrossover())){
      stats.numcro += (*scross)(*mom, *dad,
				&pop->individual(i), &pop->individual(i+1));
      c1 = c2 = 1;
    }
    else{
      pop->individual( i ).copy(*mom);
      pop->individual(i+1).copy(*dad);
    }
    stats.nummut += (mut = pop->individual( i ).mutate(pMutation()));
    if(mut > 0) c1 = 1;
    stats.nummut += (mut = pop->individual(i+1).mutate(pMutation()));
    if(mut > 0) c2 = 1;

    stats.numeval += c1 + c2;
  }
  if(pop->size() % 2 != 0){	// do the remaining population member
    mom = &(oldPop->select());  
    dad = &(oldPop->select());
    stats.numsel += 2;		// keep track of number of selections

    c1 = 0;
    if(GAFlipCoin(pCrossover())){
      stats.numcro += (*scross)(*mom, *dad, &pop->individual(i), (GAGenome*)0);
      c1 = 1;
    }
    else{
      if(GARandomBit())
	pop->individual( i ).copy(*mom);
      else
	pop->individual( i ).copy(*dad);
    }
    stats.nummut += (mut = pop->individual( i ).mutate(pMutation()));
    if(mut > 0) c1 = 1;

    stats.numeval += c1;
  }

  // Pass mpi_tasks and mpi_rank to the population clas
  pop->mpi_tasks(vmpi_tasks);
  pop->mpi_rank(vmpi_rank);

  stats.numrep += pop->size();
  pop->evaluate(gaTrue);	// get info about current pop for next time

// If we are supposed to be elitist, carry the best individual from the old
// population into the current population.  Be sure to check whether we are
// supposed to minimize or maximize.

  if(minimaxi() == GAGeneticAlgorithm::MAXIMIZE) {
    if(el && oldPop->best().score() > pop->best().score())
      oldPop->replace(pop->replace(&(oldPop->best()), GAPopulation::WORST), 
		      GAPopulation::BEST);
  }
  else {
    if(el && oldPop->best().score() < pop->best().score())
      oldPop->replace(pop->replace(&(oldPop->best()), GAPopulation::WORST), 
		      GAPopulation::BEST);
  }

  stats.update(*pop);		// update the statistics by one generation
}
Example #9
0
// Pick a single point in the 3D block and grab alternating quadrants for each
// child.  If the children are resizable, this crossover does clipping.
template <class T> int
GA3DArrayGenome<T>::
OnePointCrossover(const GAGenome& p1, const GAGenome& p2,
		  GAGenome* c1, GAGenome* c2){
  GA3DArrayGenome<T> &mom=(GA3DArrayGenome<T> &)p1;
  GA3DArrayGenome<T> &dad=(GA3DArrayGenome<T> &)p2;

  int nc=0;
  unsigned int momsitex, momlenx, momsitey, momleny, momsitez, momlenz;
  unsigned int dadsitex, dadlenx, dadsitey, dadleny, dadsitez, dadlenz;
  unsigned int sitex, lenx, sitey, leny, sitez, lenz;

  if(c1 && c2){
    GA3DArrayGenome<T> &sis=(GA3DArrayGenome<T> &)*c1;
    GA3DArrayGenome<T> &bro=(GA3DArrayGenome<T> &)*c2;

    if(sis.resizeBehaviour(GAGenome::WIDTH) == GAGenome::FIXED_SIZE &&
       bro.resizeBehaviour(GAGenome::WIDTH) == GAGenome::FIXED_SIZE){
      if(mom.width() != dad.width() || 
	 sis.width() != bro.width() || 
	 sis.width() != mom.width()){
	GAErr(GA_LOC, mom.className(), "one-point cross", gaErrSameLengthReqd);
	return nc;
      }
      sitex = momsitex = dadsitex = GARandomInt(0, mom.width());
      lenx = momlenx = dadlenx = mom.width() - momsitex;
    }
    else if(sis.resizeBehaviour(GAGenome::WIDTH) == GAGenome::FIXED_SIZE ||
	    bro.resizeBehaviour(GAGenome::WIDTH) == GAGenome::FIXED_SIZE){
      GAErr(GA_LOC, mom.className(), "one-point cross", gaErrSameBehavReqd);
      return nc;
    }
    else{
      momsitex = GARandomInt(0, mom.width());
      dadsitex = GARandomInt(0, dad.width());
      momlenx = mom.width() - momsitex;
      dadlenx = dad.width() - dadsitex;
      sitex = GAMin(momsitex, dadsitex);
      lenx = GAMin(momlenx, dadlenx);
    }
    
    if(sis.resizeBehaviour(GAGenome::HEIGHT) == GAGenome::FIXED_SIZE &&
       bro.resizeBehaviour(GAGenome::HEIGHT) == GAGenome::FIXED_SIZE){
      if(mom.height() != dad.height() || 
	 sis.height() != bro.height() || 
	 sis.height() != mom.height()){
	GAErr(GA_LOC, mom.className(), "one-point cross", gaErrSameLengthReqd);
	return nc;
      }
      sitey = momsitey = dadsitey = GARandomInt(0, mom.height());
      leny = momleny = dadleny = mom.height() - momsitey;
    }
    else if(sis.resizeBehaviour(GAGenome::HEIGHT) == GAGenome::FIXED_SIZE ||
	    bro.resizeBehaviour(GAGenome::HEIGHT) == GAGenome::FIXED_SIZE){
      GAErr(GA_LOC, mom.className(), "one-point cross", gaErrSameBehavReqd);
      return nc;
    }
    else{
      momsitey = GARandomInt(0, mom.height());
      dadsitey = GARandomInt(0, dad.height());
      momleny = mom.height() - momsitey;
      dadleny = dad.height() - dadsitey;
      sitey = GAMin(momsitey, dadsitey);
      leny = GAMin(momleny, dadleny);
    }

    if(sis.resizeBehaviour(GAGenome::DEPTH) == GAGenome::FIXED_SIZE &&
       bro.resizeBehaviour(GAGenome::DEPTH) == GAGenome::FIXED_SIZE){
      if(mom.depth() != dad.depth() || 
	 sis.depth() != bro.depth() || 
	 sis.depth() != mom.depth()){
	GAErr(GA_LOC, mom.className(), "one-point cross", gaErrSameLengthReqd);
	return nc;
      }
      sitez = momsitez = dadsitez = GARandomInt(0, mom.depth());
      lenz = momlenz = dadlenz = mom.depth() - momsitez;
    }
    else if(sis.resizeBehaviour(GAGenome::DEPTH) == GAGenome::FIXED_SIZE ||
	    bro.resizeBehaviour(GAGenome::DEPTH) == GAGenome::FIXED_SIZE){
      GAErr(GA_LOC, mom.className(), "one-point cross", gaErrSameBehavReqd);
      return nc;
    }
    else{
      momsitez = GARandomInt(0, mom.depth());
      dadsitez = GARandomInt(0, dad.depth());
      momlenz = mom.depth() - momsitez;
      dadlenz = dad.depth() - dadsitez;
      sitez = GAMin(momsitez, dadsitez);
      lenz = GAMin(momlenz, dadlenz);
    }

    sis.resize(sitex+lenx, sitey+leny, sitez+lenz);
    bro.resize(sitex+lenx, sitey+leny, sitez+lenz);

    sis.copy(mom, 
	     0, 0, 0, 
	     momsitex-sitex, momsitey-sitey, momsitez-sitez,
	     sitex, sitey, sitez);
    sis.copy(dad,
	     sitex, 0, 0,
	     dadsitex, dadsitey-sitey, dadsitez-sitez,
	     lenx, sitey, sitez);
    sis.copy(dad,
	     0, sitey, 0,
	     dadsitex-sitex, dadsitey, dadsitez-sitez,
	     sitex, leny, sitez);
    sis.copy(mom,
	     sitex, sitey, 0,
	     momsitex, momsitey, momsitez-sitez,
	     lenx, leny, sitez);
    sis.copy(dad, 
	     0, 0, sitez, 
	     dadsitex-sitex, dadsitey-sitey, dadsitez,
	     sitex, sitey, lenz);
    sis.copy(mom,
	     sitex, 0, sitez,
	     momsitex, momsitey-sitey, momsitez,
	     lenx, sitey, lenz);
    sis.copy(mom,
	     0, sitey, sitez,
	     momsitex-sitex, momsitey, momsitez,
	     sitex, leny, lenz);
    sis.copy(dad,
	     sitex, sitey, sitez,
	     dadsitex, dadsitey, dadsitez,
	     lenx, leny, lenz);
    
    bro.copy(dad, 
	     0, 0, 0, 
	     dadsitex-sitex, dadsitey-sitey, dadsitez-sitez,
	     sitex, sitey, sitez);
    bro.copy(mom,
	     sitex, 0, 0,
	     momsitex, momsitey-sitey, momsitez-sitez,
	     lenx, sitey, sitez);
    bro.copy(mom,
	     0, sitey, 0,
	     momsitex-sitex, momsitey, momsitez-sitez,
	     sitex, leny, sitez);
    bro.copy(dad,
	     sitex, sitey, 0,
	     dadsitex, dadsitey, dadsitez-sitez,
	     lenx, leny, sitez);
    bro.copy(mom, 
	     0, 0, sitez, 
	     momsitex-sitex, momsitey-sitey, momsitez,
	     sitex, sitey, lenz);
    bro.copy(dad,
	     sitex, 0, sitez,
	     dadsitex, dadsitey-sitey, dadsitez,
	     lenx, sitey, lenz);
    bro.copy(dad,
	     0, sitey, sitez,
	     dadsitex-sitex, dadsitey, dadsitez,
	     sitex, leny, lenz);
    bro.copy(mom,
	     sitex, sitey, sitez,
	     momsitex, momsitey, momsitez,
	     lenx, leny, lenz);

    nc = 2;
  }
  else if(c1){
    GA3DArrayGenome<T> &sis=(GA3DArrayGenome<T> &)*c1;

    if(sis.resizeBehaviour(GAGenome::WIDTH) == GAGenome::FIXED_SIZE){
      if(mom.width() != dad.width() || sis.width() != mom.width()){
	GAErr(GA_LOC, mom.className(), "one-point cross", gaErrSameLengthReqd);
	return nc;
      }
      sitex = momsitex = dadsitex = GARandomInt(0, mom.width());
      lenx = momlenx = dadlenx = mom.width() - momsitex;
    }
    else{
      momsitex = GARandomInt(0, mom.width());
      dadsitex = GARandomInt(0, dad.width());
      momlenx = mom.width() - momsitex;
      dadlenx = dad.width() - dadsitex;
      sitex = GAMin(momsitex, dadsitex);
      lenx = GAMin(momlenx, dadlenx);
    }
    
    if(sis.resizeBehaviour(GAGenome::HEIGHT) == GAGenome::FIXED_SIZE){
      if(mom.height() != dad.height() || sis.height() != mom.height()){
	GAErr(GA_LOC, mom.className(), "one-point cross", gaErrSameLengthReqd);
	return nc;
      }
      sitey = momsitey = dadsitey = GARandomInt(0, mom.height());
      leny = momleny = dadleny = mom.height() - momsitey;
    }
    else{
      momsitey = GARandomInt(0, mom.height());
      dadsitey = GARandomInt(0, dad.height());
      momleny = mom.height() - momsitey;
      dadleny = dad.height() - dadsitey;
      sitey = GAMin(momsitey, dadsitey);
      leny = GAMin(momleny, dadleny);
    }

    if(sis.resizeBehaviour(GAGenome::DEPTH) == GAGenome::FIXED_SIZE){
      if(mom.depth() != dad.depth() || sis.depth() != mom.depth()){
	GAErr(GA_LOC, mom.className(), "one-point cross", gaErrSameLengthReqd);
	return nc;
      }
      sitez = momsitez = dadsitez = GARandomInt(0, mom.depth());
      lenz = momlenz = dadlenz = mom.depth() - momsitez;
    }
    else{
      momsitez = GARandomInt(0, mom.depth());
      dadsitez = GARandomInt(0, dad.depth());
      momlenz = mom.depth() - momsitez;
      dadlenz = dad.depth() - dadsitez;
      sitez = GAMin(momsitez, dadsitez);
      lenz = GAMin(momlenz, dadlenz);
    }
    
    sis.resize(sitex+lenx, sitey+leny, sitez+lenz);
    
    if(GARandomBit()){
      sis.copy(mom, 
	       0, 0, 0, 
	       momsitex-sitex, momsitey-sitey, momsitez-sitez,
	       sitex, sitey, sitez);
      sis.copy(dad,
	       sitex, 0, 0,
	       dadsitex, dadsitey-sitey, dadsitez-sitez,
	       lenx, sitey, sitez);
      sis.copy(dad,
	       0, sitey, 0,
	       dadsitex-sitex, dadsitey, dadsitez-sitez,
	       sitex, leny, sitez);
      sis.copy(mom,
	       sitex, sitey, 0,
	       momsitex, momsitey, momsitez-sitez,
	       lenx, leny, sitez);
      sis.copy(dad, 
	       0, 0, sitez, 
	       dadsitex-sitex, dadsitey-sitey, dadsitez,
	       sitex, sitey, lenz);
      sis.copy(mom,
	       sitex, 0, sitez,
	       momsitex, momsitey-sitey, momsitez,
	       lenx, sitey, lenz);
      sis.copy(mom,
	       0, sitey, sitez,
	       momsitex-sitex, momsitey, momsitez,
	       sitex, leny, lenz);
      sis.copy(dad,
	       sitex, sitey, sitez,
	       dadsitex, dadsitey, dadsitez,
	       lenx, leny, lenz);
    }
    else{
      sis.copy(dad, 
	       0, 0, 0, 
	       dadsitex-sitex, dadsitey-sitey, dadsitez-sitez,
	       sitex, sitey, sitez);
      sis.copy(mom,
	       sitex, 0, 0,
	       momsitex, momsitey-sitey, momsitez-sitez,
	       lenx, sitey, sitez);
      sis.copy(mom,
	       0, sitey, 0,
	       momsitex-sitex, momsitey, momsitez-sitez,
	       sitex, leny, sitez);
      sis.copy(dad,
	       sitex, sitey, 0,
	       dadsitex, dadsitey, dadsitez-sitez,
	       lenx, leny, sitez);
      sis.copy(mom, 
	       0, 0, sitez, 
	       momsitex-sitex, momsitey-sitey, momsitez,
	       sitex, sitey, lenz);
      sis.copy(dad,
	       sitex, 0, sitez,
	       dadsitex, dadsitey-sitey, dadsitez,
	       lenx, sitey, lenz);
      sis.copy(dad,
	       0, sitey, sitez,
	       dadsitex-sitex, dadsitey, dadsitez,
	       sitex, leny, lenz);
      sis.copy(mom,
	       sitex, sitey, sitez,
	       momsitex, momsitey, momsitez,
	       lenx, leny, lenz);
    }

    nc = 1;
  }

  return nc;
}
Example #10
0
// Make sure our bitmask is big enough, generate a mask, then use it to 
// extract the information from each parent to stuff the two children.
// We don't deallocate any space for the masks under the assumption that we'll
// have to use them again in the future.
//   For now we'll implement this only for fixed length genomes.  If you use
// this crossover method on genomes of different sizes it might break!
template <class T> int
GA3DArrayGenome<T>::
UniformCrossover(const GAGenome& p1, const GAGenome& p2,
		 GAGenome* c1, GAGenome* c2){
  GA3DArrayGenome<T> &mom=(GA3DArrayGenome<T> &)p1;
  GA3DArrayGenome<T> &dad=(GA3DArrayGenome<T> &)p2;

  int nc=0;
  int i,j,k;

  if(c1 && c2){
    GA3DArrayGenome<T> &sis=(GA3DArrayGenome<T> &)*c1;
    GA3DArrayGenome<T> &bro=(GA3DArrayGenome<T> &)*c2;

    if(sis.width() == bro.width() && sis.height() == bro.height() &&
       sis.depth() == bro.depth() &&
       mom.width() == dad.width() && mom.height() == dad.height() &&
       mom.depth() == dad.depth() &&
       sis.width() == mom.width() && sis.height() == mom.height() &&
       sis.depth() == mom.depth()){
      for(i=sis.width()-1; i>=0; i--){
	for(j=sis.height()-1; j>=0; j--){
	  for(k=sis.depth()-1; k>=0; k--){
	    if(GARandomBit()){
	      sis.gene(i,j,k, mom.gene(i,j,k));
	      bro.gene(i,j,k, dad.gene(i,j,k));
	    }
	    else{
	      sis.gene(i,j,k, dad.gene(i,j,k));
	      bro.gene(i,j,k, mom.gene(i,j,k));
	    }
	  }
	}
      }
    }
    else{
      GAMask mask;
      int startx, starty, startz;
      int maxx = (sis.width() > bro.width()) ? sis.width() : bro.width();
      int minx = (mom.width() < dad.width()) ? mom.width() : dad.width();
      int maxy = (sis.height() > bro.height()) ? sis.height() : bro.height();
      int miny = (mom.height() < dad.height()) ? mom.height() : dad.height();
      int maxz = (sis.depth() > bro.depth()) ? sis.depth() : bro.depth();
      int minz = (mom.depth() < dad.depth()) ? mom.depth() : dad.depth();
      mask.size(maxx*maxy*maxz);
      for(i=0; i<maxx; i++)
	for(j=0; j<maxy; j++)
	  for(k=0; k<maxz; k++)
	    mask[i*maxy*maxz+j*maxz+k] = GARandomBit();
      startx = (sis.width() < minx) ? sis.width() : minx;
      starty = (sis.height() < miny) ? sis.height() : miny;
      startz = (sis.depth() < minz) ? sis.depth() : minz;
      for(i=startx-1; i>=0; i--)
	for(j=starty-1; j>=0; j--)
	  for(k=startz-1; k>=0; k--)
	    sis.gene(i,j,k, (mask[i*starty*startz+j*startz+k] ?
			     mom.gene(i,j,k) : dad.gene(i,j,k)));
      startx = (bro.width() < minx) ? bro.width() : minx;
      starty = (bro.height() < miny) ? bro.height() : miny;
      startz = (bro.depth() < minz) ? bro.depth() : minz;
      for(i=startx-1; i>=0; i--)
	for(j=starty-1; j>=0; j--)
	  for(k=startz-1; k>=0; k--)
	    bro.gene(i,j,k, (mask[i*starty*startz+j*startz+k] ?
			     dad.gene(i,j,k) : mom.gene(i,j,k)));
    }

    nc = 2;
  }
  else if(c1){
    GA3DArrayGenome<T> &sis=(GA3DArrayGenome<T> &)*c1;

    if(mom.width() == dad.width() && mom.height() == dad.height() &&
       mom.depth() == dad.depth() &&
       sis.width() == mom.width() && sis.height() == mom.height() &&
       sis.depth() == mom.depth()){
      for(i=sis.width()-1; i>=0; i--)
	for(j=sis.height()-1; j>=0; j--)
	  for(k=sis.depth()-1; k>=0; k--)
	    sis.gene(i,j,k, (GARandomBit() ? mom.gene(i,j,k):dad.gene(i,j,k)));
    }
    else{
      int minx = (mom.width() < dad.width()) ? mom.width() : dad.width();
      int miny = (mom.height() < dad.height()) ? mom.height() : dad.height();
      int minz = (mom.depth() < dad.depth()) ? mom.depth() : dad.depth();
      minx = (sis.width() < minx) ? sis.width() : minx;
      miny = (sis.height() < miny) ? sis.height() : miny;
      minz = (sis.depth() < minz) ? sis.depth() : minz;
      for(i=minx-1; i>=0; i--)
	for(j=miny-1; j>=0; j--)
	  for(k=minz-1; k>=0; k--)
	    sis.gene(i,j,k, (GARandomBit() ? mom.gene(i,j,k):dad.gene(i,j,k)));
    }

    nc = 1;
  }

  return nc;
}
Example #11
0
int
GA3DBinaryStringGenome::resize(int w, int h, int d)
{
  if(w == (int)nx && h == (int)ny && d == (int)nz) return sz;

  if(w == GAGenome::ANY_SIZE)
    w = GARandomInt(minX, maxX);
  else if(w < 0)
    w = nx;		// do nothing
  else if(minX == maxX)
    minX=maxX = w;
  else{
    if(w < (int)minX) w=minX;
    if(w > (int)maxX) w=maxX;
  }

  if(h == GAGenome::ANY_SIZE)
    h = GARandomInt(minY, maxY);
  else if(h < 0)
    h = ny;		// do nothing
  else if(minY == maxY)
    minY=maxY = h;
  else{
    if(h < (int)minY) h=minY;
    if(h > (int)maxY) h=maxY;
  }

  if(d == GAGenome::ANY_SIZE)
    d = GARandomInt(minZ, maxZ);
  else if(d < 0)
    d = nz;		// do nothing
  else if(minZ == maxZ)
    minZ=maxZ = d;
  else{
    if(d < (int)minZ) d=minZ;
    if(d > (int)maxZ) d=maxZ;
  }

  if(w < (int)nx && h < (int)ny){
    int z=GAMin((int)nz,d);
    for(int k=0; k<z; k++)
      for(int j=0; j<h; j++)
	GABinaryString::move(k*h*w+j*w,k*ny*nx+j*nx,w);
  }
  else if(w < (int)nx){
    int z=GAMin((int)nz,d);
    for(int k=0; k<z; k++)
      for(int j=0; j<(int)ny; j++)
	GABinaryString::move(k*ny*w+j*w,k*ny*nx+j*nx,w);
  }
  else if(h < (int)ny){
    int z=GAMin((int)nz,d);
    for(int k=0; k<z; k++)
      for(int j=0; j<h; j++)
	GABinaryString::move(k*h*nx+j*nx,k*ny*nx+j*nx,nx);
  }

  GABinaryString::resize(w*h*d);

  if(w > (int)nx && h > (int)ny){ // adjust the existing bits
    int z=GAMin((int)nz,d);
    for(int k=z-1; k>=0; k--){
      int j;
      for(j=ny-1; j>=0; j--){
	GABinaryString::move(k*h*w+j*w,k*ny*nx+j*nx,nx);
	for(int i=nx; i<w; i++)
	  bit(k*h*w+j*w+i, GARandomBit());
      }
      for(j=ny; j<h; j++)
	for(int i=0; i<w; i++)
	  bit(k*h*w+j*w+i, GARandomBit());
    }
  }
  else if(w > (int)nx){
    int z=GAMin((int)nz,d);
    for(int k=z-1; k>=0; k--){
      for(int j=h-1; j>=0; j--){
	GABinaryString::move(k*h*w+j*w,k*h*nx+j*nx,nx);
	for(int i=nx; i<w; i++)
	  bit(k*h*w+j*w+i, GARandomBit());
      }
    }
  }
  else if(h > (int)ny){
    int z=GAMin((int)nz,d);
    for(int k=z-1; k>=0; k--){
      int j;
      for(j=ny-1; j>=0; j--)
	GABinaryString::move(k*h*w+j*w,k*ny*w+j*w,w);
      for(j=ny; j<h; j++)
	for(int i=0; i<w; i++)
	  bit(k*h*w+j*w+i, GARandomBit());
    }
  }
  if(d > (int)nz){		// change in depth is always new bits
    for(int i=w*h*nz; i<w*h*d; i++)
      bit(i, GARandomBit());
  }

  nx = w; ny = h; nz = d;
  _evaluated = gaFalse;
  return sz;
}
Example #12
0
// Make sure our bitmask is big enough, generate a mask, then use it to 
// extract the information from each parent to stuff the two children.
// We don't deallocate any space for the masks under the assumption that we'll
// have to use them again in the future.
//   For now we'll implement this only for fixed length genomes.  If you use
// this crossover method on genomes of different sizes it might break!
int
GA3DBinaryStringGenome::
UniformCrossover(const GAGenome& p1, const GAGenome& p2,
		 GAGenome* c1, GAGenome* c2){
  GA3DBinaryStringGenome &mom=(GA3DBinaryStringGenome &)p1;
  GA3DBinaryStringGenome &dad=(GA3DBinaryStringGenome &)p2;

  int i,j,k, nc=0;;

  if(c1 && c2){
    GA3DBinaryStringGenome &sis=(GA3DBinaryStringGenome &)*c1;
    GA3DBinaryStringGenome &bro=(GA3DBinaryStringGenome &)*c2;

    if(sis.width() == bro.width() && sis.height() == bro.height() &&
       sis.depth() == bro.depth() &&
       mom.width() == dad.width() && mom.height() == dad.height() &&
       mom.depth() == dad.depth() &&
       sis.width() == mom.width() && sis.height() == mom.height() &&
       sis.depth() == mom.depth()){
      for(i=sis.width()-1; i>=0; i--){
	for(j=sis.height()-1; j>=0; j--){
	  for(k=sis.depth()-1; k>=0; k--){
	    if(GARandomBit()){
	      sis.gene(i,j,k, mom.gene(i,j,k));
	      bro.gene(i,j,k, dad.gene(i,j,k));
	    }
	    else{
	      sis.gene(i,j,k, dad.gene(i,j,k));
	      bro.gene(i,j,k, mom.gene(i,j,k));
	    }
	  }
	}
      }
    }
    else{
      GAMask mask;
      int maxx = GAMax(sis.width(), bro.width());
      int minx = GAMin(mom.width(), dad.width());
      int maxy = GAMax(sis.height(), bro.height());
      int miny = GAMin(mom.height(), dad.height());
      int maxz = GAMax(sis.depth(), bro.depth());
      int minz = GAMin(mom.depth(), dad.depth());
      mask.size(maxx*maxy*maxz);
      for(i=0; i<maxx; i++)
	for(j=0; j<maxy; j++)
	  for(k=0; k<maxz; k++)
	    mask[i*maxy*maxz+j*maxz+k] = GARandomBit();
      minx = GAMin(sis.width(), minx);
      miny = GAMin(sis.height(), miny);
      minz = GAMin(sis.depth(), minz);
      for(i=minx-1; i>=0; i--)
	for(j=miny-1; j>=0; j--)
	  for(k=minz-1; k>=0; k--)
	    sis.gene(i,j,k, (mask[i*miny*minz+j*minz+k] ?
			     mom.gene(i,j,k) : dad.gene(i,j,k)));
      minx = GAMin(bro.width(), minx);
      miny = GAMin(bro.height(), miny);
      minz = GAMin(bro.depth(), minz);
      for(i=minx-1; i>=0; i--)
	for(j=miny-1; j>=0; j--)
	  for(k=minz-1; k>=0; k--)
	    bro.gene(i,j,k, (mask[i*miny*minz+j*minz+k] ?
			     dad.gene(i,j,k) : mom.gene(i,j,k)));
    }

    nc = 2;
  }
  else if(c1 || c2){
    GA3DBinaryStringGenome &sis =
      (c1 ? (GA3DBinaryStringGenome&)*c1 : (GA3DBinaryStringGenome&)*c2);
    
    if(mom.width() == dad.width() && mom.height() == dad.height() &&
       mom.depth() == dad.depth() &&
       sis.width() == mom.width() && sis.height() == mom.height() &&
       sis.depth() == mom.depth()){
      for(i=sis.width()-1; i>=0; i--)
	for(j=sis.height()-1; j>=0; j--)
	  for(k=sis.depth()-1; k>=0; k--)
	    sis.gene(i,j,k, (GARandomBit() ? mom.gene(i,j,k):dad.gene(i,j,k)));
    }
    else{
      int minx = GAMin(mom.width(), dad.width());
      int miny = GAMin(mom.height(), dad.height());
      int minz = GAMin(mom.depth(), dad.depth());
      minx = GAMin(sis.width(), minx);
      miny = GAMin(sis.height(), miny);
      minz = GAMin(sis.depth(), minz);
      for(i=minx-1; i>=0; i--)
	for(j=miny-1; j>=0; j--)
	  for(k=minz-1; k>=0; k--)
	    sis.gene(i,j,k, (GARandomBit() ? mom.gene(i,j,k):dad.gene(i,j,k)));
    }

    nc = 1;
  }

  return nc;
}
Example #13
0
// To evolve the genetic algorithm, we loop through all of our populations and
// evolve each one of them.  Then allow the migrator to do its thing.  Assumes
// that the tmp pop is at least as big as the largest nrepl that we'll use.  
// The master population maintains the best n individuals from each of the
// populations, and it is based on those that we keep the statistics for the
// entire genetic algorithm run.
void
GADemeGA::step() {
  int i, mut, c1, c2;
  GAGenome *mom, *dad;
  float pc;

  if(!scross) pc = 0.0;
  else        pc = pCrossover();

  for(unsigned int ii=0; ii<npop; ii++) {
    for(i=0; i<nrepl[ii]-1; i+=2){	// takes care of odd population
      mom = &(deme[ii]->select()); 
      dad = &(deme[ii]->select());
      pstats[ii].numsel += 2;
      c1 = c2 = 0;
      if(GAFlipCoin(pc)){
	pstats[ii].numcro += (*scross)(*mom, *dad, &tmppop->individual(i), 
				       &tmppop->individual(i+1));
	c1 = c2 = 1;
      }
      else{
	tmppop->individual( i ).copy(*mom);
	tmppop->individual(i+1).copy(*dad);
      }
      pstats[ii].nummut += (mut=tmppop->individual( i ).mutate(pMutation()));
      if(mut > 0) c1 = 1;
      pstats[ii].nummut += (mut=tmppop->individual(i+1).mutate(pMutation()));
      if(mut > 0) c2 = 1;
      pstats[ii].numeval += c1 + c2;
    }
    if(nrepl[ii] % 2 != 0){	// do the remaining population member
      mom = &(deme[ii]->select()); 
      dad = &(deme[ii]->select()); 
      pstats[ii].numsel += 2;
      c1 = 0;
      if(GAFlipCoin(pc)){
	pstats[ii].numcro += 
	  (*scross)(*mom, *dad, &tmppop->individual(i), (GAGenome*)0);
	c1 = 1;
      }
      else{
	if(GARandomBit()) tmppop->individual(i).copy(*mom);
	else              tmppop->individual(i).copy(*dad);
      }
      pstats[ii].nummut += (mut=tmppop->individual(i).mutate(pMutation()));
      if(mut > 0) c1 = 1;
      pstats[ii].numeval += c1;
    }

    for(i=0; i<nrepl[ii]; i++)
      deme[ii]->add(&tmppop->individual(i));
    deme[ii]->evaluate();
    deme[ii]->scale();
    for(i=0; i<nrepl[ii]; i++)
      tmppop->replace(deme[ii]->remove(GAPopulation::WORST,
				       GAPopulation::SCALED), i);
    
    pstats[ii].numrep += nrepl[ii];
  }

  migrate();

  for(unsigned int jj=0; jj<npop; jj++) {
    deme[jj]->evaluate();
    pstats[jj].update(*deme[jj]);
  }

  stats.numsel = stats.numcro = stats.nummut = stats.numrep = stats.numeval=0;
  for(unsigned int kk=0; kk<npop; kk++) {
    pop->individual(kk).copy(deme[kk]->best());
    stats.numsel += pstats[kk].numsel;
    stats.numcro += pstats[kk].numcro;
    stats.nummut += pstats[kk].nummut;
    stats.numrep += pstats[kk].numrep;
    stats.numeval += pstats[kk].numeval;
  }

  pop->touch();
  stats.update(*pop);
  for(unsigned int ll=0; ll<npop; ll++)
    stats.numpeval += pstats[ll].numpeval;
}