예제 #1
0
/// This is the default population initializer.  It simply calls the initializer
/// for each member of the population.  Then we touch the population to tell it
/// that it needs to update stats and/or sort (but we don't actually force
/// either one to occur.
///   The population object takes care of setting/unsetting the status flags.
void
GAPopulation::DefaultInitializer(GAPopulation & p)
{
    for(int i = 0; i < p.size(); i++)
    {
        p.individual(i).initialize();
    }
}
예제 #2
0
///  The default evaluator simply calls the evaluate member of each genome in
/// the population.  The population object takes care of setting/unsetting the
/// status flags for indicating when the population needs to be updated again.
void
GAPopulation::DefaultEvaluator(GAPopulation & p)
{
    for(int i = 0; i < p.size(); i++)
    {
        p.individual(i).evaluate();
    }
}
예제 #3
0
파일: GAScaling.C 프로젝트: B0RJA/GAlib-mpi
// This is an implementation of the sigma truncation scaling method descibed in
// goldberg p 124.  If the scaled fitness is less than zero, we arbitrarily set
// it to zero (thus the truncation part of 'sigma truncation').
void 
GASigmaTruncationScaling::evaluate(const GAPopulation & p) {
  for(int i=0; i<p.size(); i++){
    double f = (double)(p.individual(i).score()) - (double)(p.ave());
    f += (double)c * (double)(p.dev());
    if(f < 0) f = 0.0;
    p.individual(i).fitness((float)f);       // might lose information here!
  }
}
예제 #4
0
// This assumes that the original population contains at least one individual
// from which to grow.  If it does not, the data in the buffer will be ignored.
int
RecvPopulation(GAPopulation& pop) {
  int status = 0;
  int psize = 0;
  status = pvm_upkint(&psize, 1, 1);
  pop.size(psize);
  for(int i=0; i<pop.size() && status>=0; i++)
    status = UnpackIndividual(pop.individual(i));
  return status;
}
예제 #5
0
// This should eventually use a genome member function rather than an external.
// When we pack/unpack a population we also stuff its statistics.
int
SendPopulation(int toid, const GAPopulation& pop) {
  int status = 0;
  int psize = pop.size();
  status = pvm_initsend(PvmDataDefault);
  status = pvm_pkint(&psize, 1, 1);
  for(int i=0; i<pop.size() && status>=0; i++)
    status = PackIndividual(pop.individual(i));
  status = pvm_send(toid, MSG_INCOMING_POPULATION);
  return status;
}
예제 #6
0
파일: evolver.cpp 프로젝트: mkb218/nynex
void Evolver::initGA(float pMutation, int popSize, GABoolean elitist) {
    GAPopulation pop;
    for (; popSize > 0; --popSize) {
        try {
            Composition *c = new Composition();
            SampleBank::getInstance().initComposition(*c);
            pop.add(c);
        } catch (std::bad_alloc & e) {
            throw std::runtime_error("couldn't alloc new composition");
        }
    }
    initGA(pMutation, elitist, 0, pop);
}
예제 #7
0
파일: GAScaling.C 프로젝트: B0RJA/GAlib-mpi
// This is an implementation of the most basic form of power scaling, where the
// fitness is a function of the objective score raised to some power.  Negative
// objective scores are not allowed.  If we get one, we post an error and set
// all of the fitness scores to zero.
void 
GAPowerLawScaling::evaluate(const GAPopulation & p) {
  for(int i=0; i<p.size(); i++){
    double f = p.individual(i).score();
    if(f < 0.0){
      GAErr(GA_LOC, className(), "evaluate", gaErrPowerNegFitness);
      for(int ii=0; ii<p.size(); ii++)
	p.individual(ii).fitness(0.0);
      return;
    }
    f = pow(f,(double)k);
    p.individual(i).fitness((float)f);       // might lose information here!
  }
}
예제 #8
0
파일: GABaseGA.C 프로젝트: dbremner/galib
GAGeneticAlgorithm::GAGeneticAlgorithm(const GAPopulation& p) : 
stats(), params() {
  pop = new GAPopulation(p);
  pop->geneticAlgorithm(*this);

  ud = nullptr;
  cf = GAGeneticAlgorithm::DEFAULT_TERMINATOR;

  d_seed = gaDefSeed;
  params.add(gaNseed, gaSNseed, GAParameter::INT, &d_seed);

  minmax = gaDefMiniMaxi;
  params.add(gaNminimaxi, gaSNminimaxi, GAParameter::INT, &minmax);
  ngen = gaDefNumGen;
  params.add(gaNnGenerations, gaSNnGenerations, GAParameter::INT, &ngen);
  nconv = gaDefNConv; stats.nConvergence(nconv);
  params.add(gaNnConvergence, gaSNnConvergence, GAParameter::INT, &nconv);
  pconv = gaDefPConv;
  params.add(gaNpConvergence, gaSNpConvergence, GAParameter::FLOAT, &pconv);
  pcross = gaDefPCross;
  params.add(gaNpCrossover, gaSNpCrossover, GAParameter::FLOAT, &pcross);
  pmut = gaDefPMut;
  params.add(gaNpMutation, gaSNpMutation, GAParameter::FLOAT, &pmut);
  int psize = pop->size();
  params.add(gaNpopulationSize, gaSNpopulationSize, GAParameter::INT, &psize);

  stats.scoreFrequency(gaDefScoreFrequency1);
  params.add(gaNscoreFrequency, gaSNscoreFrequency,
	     GAParameter::INT, &gaDefScoreFrequency1);
  stats.flushFrequency(gaDefFlushFrequency);
  params.add(gaNflushFrequency, gaSNflushFrequency,
	     GAParameter::INT, &gaDefFlushFrequency);
  stats.recordDiversity(gaDefDivFlag);
  params.add(gaNrecordDiversity, gaSNrecordDiversity, 
	     GAParameter::INT, &gaDefDivFlag);
  stats.scoreFilename(gaDefScoreFilename);
  params.add(gaNscoreFilename, gaSNscoreFilename, 
	     GAParameter::STRING, gaDefScoreFilename);
  stats.selectScores(gaDefSelectScores);
  params.add(gaNselectScores, gaSNselectScores, 
	     GAParameter::INT, &gaDefSelectScores);
  stats.nBestGenomes(p.individual(0), gaDefNumBestGenomes);
  params.add(gaNnBestGenomes, gaSNnBestGenomes,
	     GAParameter::INT, &gaDefNumBestGenomes);

  scross = p.individual(0).sexual();
  across = p.individual(0).asexual();
}
예제 #9
0
// Set the score info to the appropriate values.  Update the score count.
void
GAStatistics::setScore(const GAPopulation& pop){ 
  aveCur = pop.ave();
  maxCur = pop.max();
  minCur = pop.min();
  devCur = pop.dev();
  divCur = ((dodiv == gaTrue) ? pop.div() : (float)-1.0);

  if(Nscrs == 0) return;
  gen[nscrs] = curgen;
  aveScore[nscrs] = aveCur;
  maxScore[nscrs] = maxCur;
  minScore[nscrs] = minCur;
  devScore[nscrs] = devCur;
  divScore[nscrs] = divCur;
  nscrs++;
}
예제 #10
0
GADemeGA::GADemeGA(const GAPopulation& p) : GAGeneticAlgorithm(p) {
  if(p.size() < 1) {
    GAErr(GA_LOC, className(), "GADemeGA(GAPopulation&)", gaErrNoIndividuals);
    pop = 0; nrepl = 0; tmppop = 0; pstats = 0;
  }
  else {
    npop = gaDefNPop;
    params.add(gaNnPopulations, gaSNnPopulations, GAParameter::INT, &npop);
    nmig = gaDefNMig;
    params.add(gaNnMigration, gaSNnMigration, GAParameter::INT, &nmig);
    unsigned int nr = pop->size()/2;

    nrepl = new int [npop];
    deme = new GAPopulation* [npop];
    pstats = new GAStatistics [npop];
    tmppop = new GAPopulation(p.individual(0), nr);
    
    for(unsigned int i=0; i<npop; i++) {
      nrepl[i] = nr;
      deme[i] = new GAPopulation(p);
    }
  }
}
예제 #11
0
int main(int argc, const char * argv[])
{
    srand((unsigned)time(NULL));
    
    printf("Running Genetic Algorithm...\n");
    printf("Target Genes: %s\n", kTargetGenes.c_str());
    printf("Population Size: %d\n", kPopulationSize);
    printf("Elitism: %s\n", (kElitismEnabled ? "true" : "false"));
    printf("Elitism Percentage: %d%%\n", kElitismPercentage);
    printf("Mutation Probability: %d%%\n", kMutationProbability);
    printf("Crossover Probability: %d%%\n\n", kCrossoverProbability);
    
    GAPopulation population = GAPopulation(kPopulationSize, kTargetGenes);
    population.elitismEnabled = kElitismEnabled;
    population.tournamentSize = kTournamentSize;
    population.elitismPercentage = PERCENTAGE(kElitismPercentage);
    population.mutationProbability = PERCENTAGE(kMutationProbability);
    population.crossoverProbability = PERCENTAGE(kCrossoverProbability);
    population.selectionType = GAPopulationSelectionType::GAPopulationSelectionTypeTournament;
    population.crossoverType = GAPopulationCrossoverType::GAPopulationCrossoverTypeOnePoint;
    population.evolve();
    
    return 0;
}
예제 #12
0
파일: GAScaling.C 프로젝트: B0RJA/GAlib-mpi
void 
GALinearScaling::evaluate(const GAPopulation & p) {
// Here we calculate the slope and intercept using the multiplier and objective
// score ranges...

  double pmin = p.min();
  double pmax = p.max();
  double pave = p.ave();

  double delta, a, b;
  if(pave == pmax){	// no scaling - population is all the same
    a = 1.0; 
    b = 0.0;
  }
  else if(pmin > ((double)c * pave - pmax)/((double)c - 1.0)){
    delta = pmax - pave;
    a = ((double)c - 1.0) * pave / delta;
    b = pave * (pmax - (double)c * pave) / delta;
  }
  else{				// stretch to make min be 0
    delta = pave - pmin;
    a = pave / delta;
    b = -pmin * pave / delta;
  }

// and now we calculate the scaled scaled values.  Negative scores are not
// allowed with this kind of scaling, so check for negative values.  If we get
// a negative value, dump an error message then set all of the scores to 0.

  for(int i=0; i<p.size(); i++){
    double f = p.individual(i).score();
    if(f < 0.0){
      GAErr(GA_LOC, className(), "evaluate", gaErrNegFitness);
      for(int ii=0; ii<p.size(); ii++)
	p.individual(ii).fitness(0.0);
      return;
    }
    f = f * a + b;
    if(f < 0) f = 0.0;	// truncate if necessary (only due to roundoff error)
    p.individual(i).fitness((float)f);       // might lose information here!
  }
}
예제 #13
0
//   This population evaluator is the administrator for the parallelization.
// It looks around to see when slaves are available to evaluate a genome.  As
// soon as a slave is available and a genome needs to be evaluated, this 
// routine sends it off.  When a slave is finished, it posts a message to 
// say so and this routine gets the message and grabs the results from the 
// slave that posted the message.
//   An index of -1 means that the slave has no assignment.  The first int in 
// the stream of stuff is always the ID of the slave (0-nslaves) that is 
// sending the information.  After that it is either nothing (the slave just 
// reported that it is ready for another genome) or it is a float (the score 
// of the genome that was assigned to the slave).
void 
PopulationEvaluator(GAPopulation& pop) {
  PVMDataPtr data = (PVMDataPtr)pop.userData();
  int* index = new int [data->nreq];
  int done = 0, outstanding = 0, next = 0;
  int bufid, status, bytes, msgtag, tid, who;

  while(!done) {
// If we have a genome that needs to be evaluated and one of the slaves is
// ready to evaluate it, send the genome to the slave.
    if(next < pop.size() && (bufid=pvm_nrecv(-1, MSG_READY)) != 0) {
      if(bufid > 0) {
	pvm_bufinfo(bufid, &bytes, &msgtag, &tid);
	status = SendGenomeData(pop.individual(next), tid);
	if(status >= 0) {
	  if((who = id2idx(tid, *data)) >= 0) {
	    index[who] = next; next++;
	    outstanding++;
	  }
	  else {
	    cerr << "PopEval: bogus tid mapping: " << tid << "\n";
	  }
	}
	else {
	  cerr << "PopEval: error sending data to: " << tid;
	  cerr << "  error code is: " << status << "\n";
	}
      }
      else {
	cerr << "PopEval: error from pvm_nrecv: " << bufid << "\n";
      }
    }

// If we have any genomes waiting for their evaluation and any slaves have 
// posted a message stating that they have a finished score ready for us, get
// the score from the slave and stuff it into the appropriate genome.
    if(outstanding > 0 && (bufid=pvm_nrecv(-1, MSG_GENOME_SCORE)) != 0) {
      if(bufid > 0) {
	pvm_bufinfo(bufid, &bytes, &msgtag, &tid);
	if((who = id2idx(tid, *data)) >= 0) {
	  if(index[who] >= 0) {
	    status = RecvGenomeScore(pop.individual(index[who]));
	    if(status >= 0) {
	      index[who] = -1;
	      outstanding--;
	    }
	    else {
	      cerr << "PopEval: error receiving score from: " << tid;
	      cerr << "  error code is: " << status << "\n";
	    }
	  }
	  else {
	    cerr << "PopEval: index conflict from tid " << tid << "\n";
	  }
	}
	else {
	  cerr << "PopEval: bogus tid mapping: " << tid << "\n";
	}
      }
      else {
	cerr << "PopEval: error from pvm_nrecv: " << bufid << "\n";
      }
    }

    if(next == pop.size() && outstanding == 0) done = 1;
    if(next > pop.size()) {
      cerr << "bogus value for next: " << next;
      cerr << "  popsize is: " << pop.size() << "\n";
    }
  }

  delete [] index;
}
예제 #14
0
// The population initializer invokes the genomes' initializers just like the
// standard population initializer, but here we farm out the genomes to the
// slaves before invoking the initialization.  Farm out the genomes and give
// the slaves the initialize command rather than the evaluate command.
void
PopulationInitializer(GAPopulation& pop) {
  PVMDataPtr data = (PVMDataPtr)pop.userData();
  int* index = new int [data->nreq];
  int done = 0, outstanding = 0, next = 0;
  int bufid, status, bytes, msgtag, tid, who;

  while(!done) {
// If we have a genome that needs to be initialized and one of the slaves is
// available, then ask the slave to configure a genome and send us back the
// configured, initialized genome.
    if(next < pop.size() && (bufid=pvm_nrecv(-1, MSG_READY)) != 0) {
      if(bufid > 0) {
	status = pvm_bufinfo(bufid, &bytes, &msgtag, &tid);
	status = SendGenomeInitialize(pop.individual(next), tid);
	if(status >= 0) {
	  if((who = id2idx(tid, *data)) >= 0) {
	    index[who] = next; next++;
	    outstanding++;
	  }
	  else {
	    cerr << "PopInit: bogus tid mapping: " << tid << "\n";
	  }
	}
	else {
	  cerr << "PopInit: error sending initialize command to: " << tid;
	  cerr << "  genome " << next << " will be inited by next slave\n";
	  cerr << "  error code is: " << status << "\n";
	}
      }
      else {
	cerr << "PopInit: error from pvm_nrecv: " << bufid << "\n";
      }
    }

// If we have requests for initialization outstanding and a slave has posted
// a message stating that it will provide genome data, then get the data from
// the slave and stuff it into the appropriate genome in the population.
    if(outstanding > 0 && (bufid=pvm_nrecv(-1, MSG_GENOME_DATA)) != 0) {
      if(bufid > 0) {
	status = pvm_bufinfo(bufid, &bytes, &msgtag, &tid);
	if((who = id2idx(tid, *data)) >= 0) {
	  if(index[who] >= 0) {
	    status = RecvGenomeData(pop.individual(index[who]));
	    if(status >= 0) {
	      index[who] = -1;
	      outstanding--;
	    }
	    else {
	      cerr << "PopInit: error receiving data from: " << tid;
	      cerr << "  error code is: " << status << "\n";
	    }
	  }
	  else {
	    cerr << "PopInit: index conflict from tid " << tid << "\n";
	  }
	}
	else {
	  cerr << "PopInit: bogus tid mapping: " << tid << "\n";
	}
      }
      else {
	cerr << "PopInit: error from pvm_nrecv: " << bufid << "\n";
      }
    }

    if(next == pop.size() && outstanding == 0) done = 1;
    if(next > pop.size()) {
      cerr << "bogus value for next: " << next;
      cerr << "  popsize is: " << pop.size() << "\n";
    }
  }

  delete [] index;
}
예제 #15
0
// Reset the GA's statistics based on the population.  To do this right you
// should initialize the population before you pass it to this routine.  If you
// don't, the stats will be based on a non-initialized population.
void
GAStatistics::reset(const GAPopulation & pop){
  curgen = 0;
  numsel = numcro = nummut = numrep = numeval = numpeval = 0;

  memset(gen, 0, Nscrs*sizeof(int));
  memset(aveScore, 0, Nscrs*sizeof(float));
  memset(maxScore, 0, Nscrs*sizeof(float));
  memset(minScore, 0, Nscrs*sizeof(float));
  memset(devScore, 0, Nscrs*sizeof(float));
  memset(divScore, 0, Nscrs*sizeof(float));
  nscrs = 0;
  setScore(pop);
  if(Nscrs > 0) flushScores();

  memset(cscore, 0, Nconv*sizeof(float));
  nconv = 0;			// should set to -1 then call setConv
  cscore[0] = 
    ((pop.order() == GAPopulation::HIGH_IS_BEST) ? pop.max() : pop.min());
//  cscore[0] = pop.max();
//  setConvergence(maxScore[0]);

  updateBestIndividual(pop, gaTrue);
  aveCur = aveInit = pop.ave();
  maxCur = maxInit = maxever = pop.max();
  minCur = minInit = minever = pop.min();
  devCur = devInit = pop.dev();
  divCur = divInit = ((dodiv == gaTrue) ? pop.div() : (float)-1.0);

  on = pop.ave();
  offmax = pop.max();
  offmin = pop.min();
  numpeval = pop.nevals();
  for(int i=0; i<pop.size(); i++)
    numeval += pop.individual(i).nevals();
}
예제 #16
0
// Use this method to update the statistics to account for the current
// population.  This routine increments the generation counter and assumes that
// the population that gets passed is the current population.
//   If we are supposed to flush the scores, then we dump them to the specified
// file.  If no flushing frequency has been specified then we don't record.
void
GAStatistics::update(const GAPopulation & pop){
  ++curgen;			// must do this first so no divide-by-zero
  if(scoreFreq > 0 && (curgen % scoreFreq == 0)) setScore(pop);
  if(Nscrs > 0 && nscrs >= Nscrs) flushScores();
  maxever = (pop.max() > maxever) ? pop.max() : maxever;
  minever = (pop.min() < minever) ? pop.min() : minever;
  float tmpval;
  tmpval = (on*(curgen-1) + pop.ave()) / curgen;
  on = tmpval;
  tmpval = (offmax*(curgen-1) + pop.max()) / curgen;
  offmax = tmpval;
  tmpval = (offmin*(curgen-1) + pop.min()) / curgen;
  offmin = tmpval;
  setConvergence((pop.order() == GAPopulation::HIGH_IS_BEST) ?
		 pop.max() : pop.min());
  updateBestIndividual(pop);
  numpeval = pop.nevals();
}
예제 #17
0
// Update the genomes in the 'best of all' population to reflect any 
// changes made to the current population.  We just grab the genomes with
// the highest scores from the current population, and if they are higher than
// those of the genomes in the boa population, they get copied.  Note that
// the bigger the boa array, the bigger your running performance hit because
// we have to look through all of the boa to figure out which are better than
// those in the population.  The fastest way to use the boa is to keep only 
// one genome in the boa population.  A flag of 'True' will reset the boa
// population so that it is filled with the best of the current population.
//   Unfortunately it could take a long time to update the boa array using the
// copy method.  We'd like to simply keep pointers to the best genomes, but
// the genomes change from generation to generation, so we can't depend on
// that.
//   Notice that keeping boa is useful even for overlapping populations.  The
// boa keeps individuals that are different from each other - the overlapping
// population may not.  However, keeping boa is most useful for populations
// with little overlap.
//   When we check to see if a potentially better member is already in our
// best-of-all population, we use the operator== comparator not the genome
// comparator to do the comparison.
void
GAStatistics::
updateBestIndividual(const GAPopulation & pop, GABoolean flag){
  if(boa == (GAPopulation *)0 || boa->size() == 0) return; // do nothing
  if(pop.order() != boa->order()) boa->order(pop.order());

  if(flag == gaTrue){		// reset the BOA array
    int j=0;
    for(int i=0; i<boa->size(); i++){
      boa->best(i).copy(pop.best(j));
      if(j < pop.size()-1) j++;
    }
    return;
  }

  if(boa->size() == 1){		// there's only one boa so replace it with bop
    if(boa->order() == GAPopulation::HIGH_IS_BEST &&
       pop.best().score() > boa->best().score())
      boa->best().copy(pop.best());
    if(boa->order() == GAPopulation::LOW_IS_BEST &&
       pop.best().score() < boa->best().score())
      boa->best().copy(pop.best());
  }
  else{
    int i=0, j, k;
    if(boa->order() == GAPopulation::HIGH_IS_BEST) {
      while(i < pop.size() && pop.best(i).score() > boa->worst().score()){
	for(k=0;
	    pop.best(i).score() < boa->best(k).score() && k < boa->size();
	    k++);
	for(j=k; j<boa->size(); j++){
	  if(pop.best(i) == boa->best(j)) break;
	  if(pop.best(i).score() > boa->best(j).score()){
	    boa->worst().copy(pop.best(i));        // replace worst individual
	    boa->sort(gaTrue, GAPopulation::RAW);  // re-sort the population
	    break;
	  }
	}
	i++;
      }
    }
    if(boa->order() == GAPopulation::LOW_IS_BEST) {
      while(i < pop.size() && pop.best(i).score() < boa->worst().score()){
	for(k=0;
	    pop.best(i).score() > boa->best(k).score() && k < boa->size();
	    k++);
	for(j=k; j<boa->size(); j++){
	  if(pop.best(i) == boa->best(j)) break;
	  if(pop.best(i).score() < boa->best(j).score()){
	    boa->worst().copy(pop.best(i));        // replace worst individual
	    boa->sort(gaTrue, GAPopulation::RAW);  // re-sort the population
	    break;
	  }
	}
	i++;
      }
    }
  }
  return;
}
예제 #18
0
파일: GAScaling.C 프로젝트: B0RJA/GAlib-mpi
// This is an implementation of speciation using the sharing method described
// by goldberg in his book.  This requires a user-defined distance function in
// order to work.  The distance function returns a value between
// 0 and 1 inclusive to tell us how similar two genomes are to each other.
// A value of 0 means that the two genomes are identical to each other, a
// value of 1 means they are completely different.
//   A single genome is identical to itself, so d(i,i) is 0.
//   If alpha is 1 then we don't use pow().
//   If we have a comparator to use, use it.  If not, use the comparator of
// each genome.
//   We can cut in half the number of calls to the sharing function by keeping
// one half of the ixj matrix.  This is because d(i,j) is the same as d(j,i).
// We cache the distances in an upper right triangular matrix stored as a 
// series of floats.
//   If the population is maximizing then we derate by dividing.  If the 
// population is minimizing then we derate by multiplying.  First we check to 
// see if there is a GA using the population.  If there is, we use its min/max
// flag to determine whether or not we should be minimizing or maximizing.  If
// there is not GA with the population, then we use the population's sort order
// as the basis for whether to minimize or maximize.
// *** This could be done with n*n/2 instead of n*n, to reduce storage, but we
// can't reduce computation any more...
// *** probably should use the diversity built-in to the population...
void 
GASharing::evaluate(const GAPopulation& p) {
  if(p.size() > (int)N){
    delete [] d;
    N = p.size();
    d = new float[N*N];
  }
  int n = p.size();

  int i, j;
  if(df) {
    for(i=0; i<n; i++){		// calculate and cache the distances
      d[i*n+i] = 0.0;		// each genome is same as itself
      for(j=i+1; j<n; j++)
	d[i*n+j] = d[j*n+i] = (*df)(p.individual(i), p.individual(j));
    }
  }
  else {
    for(i=0; i<n; i++){		// calculate and cache the distances
      d[i*n+i] = 0.0;		// each genome is same as itself
      for(j=i+1; j<n; j++)
	d[i*n+j] = d[j*n+i] = p.individual(i).compare(p.individual(j));
    }
  }

  int mm;
  if(_minmax == 0) {
    if(p.geneticAlgorithm())
      mm = p.geneticAlgorithm()->minimaxi();
    else
      mm = ((p.order() == GAPopulation::HIGH_IS_BEST) ? 
	    GAGeneticAlgorithm::MAXIMIZE : GAGeneticAlgorithm::MINIMIZE);
  }
  else {
    mm = _minmax;
  }

  for(i=0; i<n; i++){		// now derate the fitness of each genome
    double sum = 0.0;
    for(j=0; j<n; j++) {
      if(d[i*n+j] < _sigma) {
	if(_alpha == 1)
	  sum += ((d[i*n+j] >= _sigma) ? 0.0 : 1.0 - d[i*n+j]/_sigma);
	else
	  sum += ((d[i*n+j]>=_sigma) ? 0.0 : 1.0-pow(d[i*n+j]/_sigma,_alpha));
      }
    }
    double f;
    if(mm == GAGeneticAlgorithm::MINIMIZE)
      f = p.individual(i).score() * sum;
    else
      f = p.individual(i).score() / sum;
    p.individual(i).fitness((float)f);       // might lose information here!
  }
}
예제 #19
0
파일: GAScaling.C 프로젝트: B0RJA/GAlib-mpi
// Assign the fitness scores to be the same as the objective scores for all of
// the individuals in the population.
void 
GANoScaling::evaluate(const GAPopulation& p) {
  for(int i=0; i<p.size(); i++)
    p.individual(i).fitness(p.individual(i).score());
}
void PetriDish::GAPDEvaluator( GAPopulation & pop )
{
    assert(pop.size() > 0);

    // Since this is a static method, get this population's associated PetriDish
    PetriDish* thisPetriDish = dynamic_cast<PetriDish*>(pop.geneticAlgorithm());
    assert(thisPetriDish);

#ifdef USING_GASIMPLEGA
    // A workaround for  oldPop not copying our Evaluator to the next set of Genomes (as opposed to hacking GASimpleGA.C)
    if ( thisPetriDish->_oldPopInitialized == false )
    {
        thisPetriDish->_oldPopInitialized = true;
        thisPetriDish->oldPop->initialize();
    }
#endif//USING_GASIMPLEGA

    // Use all of the available cores (as reported by the processor) for threads
    unsigned numberOfThreadsToUse;

#if USE_BOOST
    numberOfThreadsToUse = boost::thread::hardware_concurrency();
#else//USE_BOOST
    numberOfThreadsToUse = (unsigned)sysconf( _SC_NPROCESSORS_ONLN );
    int errorCode;
#endif//USE_BOOST

    // Allocate an array of pointers for the threads, as well as the associated background information
#if USE_BOOST
    boost::thread** backgroundThreads = new boost::thread*[numberOfThreadsToUse];
#else//USE_BOOST
    pthread_t* backgroundThreads = new pthread_t[numberOfThreadsToUse];
#endif//USE_BOOST
    assert( backgroundThreads );
    memset( backgroundThreads, 0, numberOfThreadsToUse * sizeof( void* ) );

    BackgroundEvaluator** backgroundEvaluators = new BackgroundEvaluator*[numberOfThreadsToUse];
    assert( backgroundEvaluators );
    memset( backgroundEvaluators, 0, numberOfThreadsToUse * sizeof( BackgroundEvaluator* ) );

#if DEBUG
    cout << "Evaluating new GAPopulation ( " << pop.size( ) << " )... ( using " << numberOfThreadsToUse << " threads )" << std::endl;
#endif//DEBUG

    int completed = 0;
    int indIndex = 0;
    u_int32_t tIndex = 0U;

#if DEBUG
    float highestScoreSoFar = 0.0f;
    float total = 0.0f;
#endif//DEBUG

    // Loop until every population member has been evaluated.
    while ( completed < pop.size( ) && ( thisPetriDish->_interrupt == false ) )
    {
        // If we still have members to evaluate, and there's a free thread open
        if ( ( indIndex < pop.size( ) ) && ( backgroundThreads[tIndex] == NULL ) )
        {
            // If we haven't allocated space for the evaluator thread information
            if( backgroundEvaluators[tIndex] == NULL )
            {
                backgroundEvaluators[tIndex] = new BackgroundEvaluator( &pop.individual( indIndex ), indIndex );
                assert( backgroundEvaluators[tIndex] != NULL );
            }
            else
            {
                assert(backgroundEvaluators[tIndex]->finished() == true);

                backgroundEvaluators[tIndex]->newIndividual( &pop.individual( indIndex ), indIndex);
            }
#if DEBUG
            cout << "Starting individual #" << indIndex + 1 << " ( of " << pop.size( ) << " )" << std::endl;
#endif//DEBUG

            // Kick off the thread
#if USE_BOOST
            try
            {
                backgroundThreads[tIndex] = new boost::thread( boost::ref(*backgroundEvaluators[tIndex]) );
            }
            catch(const std::exception& e)
            {
                cerr << "boost::thread exception: " << e.what() << std::endl;
                return;
            }
#else//USE_BOOST
            errorCode = pthread_create(&backgroundThreads[tIndex], NULL, backgroundEvaluate, backgroundEvaluators[tIndex]);
            if (errorCode!=0)
            {
                cerr << "pthread_create: Error #"<< errorCode << " (" << strerror(errorCode) << ")" << std::endl;
                return;
            }
#endif//USE_BOOST
            assert(backgroundThreads[tIndex]);

            indIndex++;
        }

        // Our cyclic thread index checks for the completion of a running thread
        tIndex = ( tIndex+1 ) % numberOfThreadsToUse;

        // A (possibly still running) thread exists...
        if ( backgroundThreads[tIndex] != NULL )
        {
            assert( backgroundEvaluators[tIndex] != NULL );

            // Check to see if it is finished
            if ( backgroundEvaluators[tIndex]->finished() )
            {
                // The thread has finished. Gather some stats (if DEBUGging) and free the thread up for the next individual
                completed++;
#if DEBUG
                GAGenome* genome = backgroundEvaluators[tIndex]->individual( );

                float score = genome->score( );

                total += score;

                cout << "Received results from individual #" << backgroundEvaluators[tIndex]->index( ) << " ( " << completed << " of " << pop.size( ) <<
                     " finished ): Score: " << genome->score( ) << " (" << total / (float)completed << " is average so far)" << std::endl;

                if ( score > highestScoreSoFar )
                {
                    cout << "Found new high score so far: ( " << score << " > " << highestScoreSoFar <<" )" << std::endl;
                    highestScoreSoFar = score;
                }
#endif//DEBUG
#if USE_BOOST
                delete backgroundThreads[tIndex];
#else//USE_BOOST
                errorCode = pthread_join(backgroundThreads[tIndex], NULL);
                assert(errorCode==0);
#endif//USE_BOOST
                backgroundThreads[tIndex] = NULL;
            }
            else
            {
                // If it hasn't finished yet, give up some main() thread processor time to the background evaluators
#if USE_BOOST
                boost::thread::yield();
#else//USE_BOOST
                pthread_yield();
#endif//USE_BOOST
            }
        }
    }

    if ( thisPetriDish->_interrupt == true )
    {
        cerr << "...evaluation interrupted!" << std::endl;

        thisPetriDish->terminator(InterruptTerminator);
    }
#if DEBUG
    else
    {
        cout << "...finished evaluating this population." << std::endl;
    }
#endif//DEBUG

    for ( tIndex = 0; tIndex < numberOfThreadsToUse; tIndex++ )
    {
        if ( thisPetriDish->_interrupt == false )
        {
            // Double (sanity) check that all of the threads have actually been processed
            assert( backgroundThreads[tIndex] == NULL );

            if ( backgroundEvaluators[tIndex] != NULL ) // This can happen if all cores aren't used
            {
                assert( backgroundEvaluators[tIndex]->finished() == true );
            }
        }
        else
        {
            // If the GA has been interrupted, try and clean up the background threads
            if ( backgroundThreads[tIndex] != NULL )
            {
#if USE_BOOST
                backgroundThreads[tIndex]->interrupt();
                delete backgroundThreads[tIndex];
#else//USE_BOOST
                pthread_cancel(backgroundThreads[tIndex]);
                errorCode = pthread_join(backgroundThreads[tIndex], NULL);
                assert(errorCode==0);
#endif//USE_BOOST
                backgroundThreads[tIndex] = NULL;
            }
        }

        if ( backgroundEvaluators[tIndex] != NULL ) // This can happen if all cores aren't used
        {
            delete backgroundEvaluators[tIndex];
            backgroundEvaluators[tIndex] = NULL;
        }
    }

    // Free up the thread and background information arrays
    if (backgroundThreads) {
        delete[] backgroundThreads;
        backgroundThreads = NULL;
    }
    if (backgroundEvaluators) {
        delete[] backgroundEvaluators;
        backgroundEvaluators = NULL;
    }
}
예제 #21
0
//  The default evaluator simply calls the evaluate member of each genome in
// the population.  The population object takes care of setting/unsetting the 
// status flags for indicating when the population needs to be updated again.
void 
GAPopulation::DefaultEvaluator(GAPopulation & p){

  // MPI aux vars
  int mpi_rc;
  MPI_Status mpi_Stat;

  // Array to store the scores of the individuals
  float *mpi_score;
  mpi_score = (float*)malloc( p.size()*sizeof(float) );

  // Each thread computes individuals from is to (ie-1)
  int is, ie;
  is = (int)((float)p.size()/(float)p.vmpi_tasks*((float)p.vmpi_rank));
  ie = (int)((float)p.size()/(float)p.vmpi_tasks*((float)p.vmpi_rank+1.0));
  if(ie>p.size() || p.vmpi_rank==(p.vmpi_tasks-1)){ ie = p.size(); }

  // Individual loop
  for(int i=is; i<ie; i++)
  {
    p.individual(i).evaluate();
    mpi_score[i] = p.individual(i).score();
  }

  // The master process:
  if(p.vmpi_rank == 0)
  {
    // recives the partial scores
    for(int i=1; i<p.vmpi_tasks; i++)
    {
      is = (int)((float)p.size()/(float)p.vmpi_tasks*((float)i));
      ie = (int)((float)p.size()/(float)p.vmpi_tasks*((float)i+1.0));
      mpi_rc = MPI_Recv(mpi_score+is, ie-is, MPI_FLOAT, i, 1, MPI_COMM_WORLD, &mpi_Stat);
    }
    // and sends the whole array
    for(int i=1; i<p.vmpi_tasks; i++)
      mpi_rc = MPI_Send(mpi_score, p.size(), MPI_FLOAT, i, 1, MPI_COMM_WORLD);
  }
  // The rest:
  else
  {
    // sends the partial computed scores
	mpi_rc = MPI_Send(mpi_score+is, ie-is, MPI_FLOAT, 0, 1, MPI_COMM_WORLD);
    // and recieves the whole array
    mpi_rc = MPI_Recv(mpi_score, p.size(), MPI_FLOAT, 0, 1, MPI_COMM_WORLD, &mpi_Stat);
  }

  // Update the scores of the individuals
  for(int i=0; i<p.size(); i++)
    p.individual(i).score(mpi_score[i]);

}
예제 #22
0
void MyEvaluator(GAPopulation &pop)
{
#pragma omp parallel for
	for(int i=0; i<pop.size(); i++)
		pop.individual(i).evaluate();
}