// This works only for enumerated sets.  If someone tries to use this on a
// non-enumerated set then we post an error message.  No bounds checking on 
// the value that was passed to us, but we do modulo it so that we'll never
// break.  Also, this means you can wrap an allele set around an array that
// is significantly larger than the allele set that defines its contents.
template <class T> T
GAAlleleSet<T>::allele(unsigned int i) const {
  if(core->type == GAAllele::ENUMERATED)
    return core->a[i % core->sz];
  else if(core->type == GAAllele::DISCRETIZED){
    GAErr(GA_LOC, "GAAlleleSet", "allele(unsigned int)", gaErrOpUndef);
    return core->a[0];
  }
  else{
    GAErr(GA_LOC, "GAAlleleSet", "allele(unsigned int)", gaErrNoAlleleIndex);
    return core->a[0];
  }
}
// When returning an allele from the set, we have to know what type we are.
// The allele that we return depends on the type.  If we're an enumerated set
// then just pick randomly from the list of alleles.  If we're a bounded set
// then pick randomly from the bounds, and respect the bound types.  If we're 
// a discretized set then we do much as we would for the bounded set, but we 
// respect the discretization.
//   Be sure to specialize this member function (see the real genome for an
// example of how to do this)
template <class T> T
GAAlleleSet<T>::allele() const {
  if(core->type == GAAllele::ENUMERATED)
    return core->a[GARandomInt(0, core->sz-1)];
  else if(core->type == GAAllele::DISCRETIZED){
    GAErr(GA_LOC, "GAAlleleSet", "allele(unsigned int)", gaErrOpUndef);
    return core->a[0];
  }
  else{
    GAErr(GA_LOC, "GAAlleleSet", "allele(unsigned int)", gaErrOpUndef);
    return core->a[0];
  }
}
Beispiel #3
0
template <class T> int
GA3DArrayGenome<T>::
resizeBehaviour(GAGenome::Dimension which, 
		unsigned int lower, unsigned int upper)
{
  if(upper < lower){
    GAErr(GA_LOC, className(), "resizeBehaviour", gaErrBadResizeBehaviour);
    return resizeBehaviour(which);
  }

  switch(which){
  case WIDTH:
    minX = lower; maxX = upper;
    if(nx > upper) GA3DArrayGenome<T>::resize(upper,ny,nz);
    if(nx < lower) GA3DArrayGenome<T>::resize(lower,ny,nz);
    break;

  case HEIGHT:
    minY = lower; maxY = upper;
    if(ny > upper) GA3DArrayGenome<T>::resize(nx,upper,nz);
    if(ny < lower) GA3DArrayGenome<T>::resize(nx,lower,nz);
    break;

  case DEPTH:
    minZ = lower; maxZ = upper;
    if(nz > upper) GA3DArrayGenome<T>::resize(nx,ny,upper);
    if(nz < lower) GA3DArrayGenome<T>::resize(nx,ny,lower);
    break;

  default:
    break;
  }

  return resizeBehaviour(which);
}
Beispiel #4
0
int
GA2DBinaryStringGenome::
resizeBehaviour(Dimension which, unsigned int lower, unsigned int upper)
{
  if(upper < lower){
    GAErr(GA_LOC, className(), "resizeBehaviour", gaErrBadResizeBehaviour);
    return resizeBehaviour(which);
  }

  switch(which){
  case WIDTH:
    minX = lower; maxX = upper;
    if(nx > upper) resize(upper,ny);
    if(nx < lower) resize(lower,ny);
    break;

  case HEIGHT:
    minY = lower; maxY = upper;
    if(ny > upper) resize(nx,upper);
    if(ny < lower) resize(nx,lower);
    break;

  default:
    break;
  }

  return resizeBehaviour(which);
}
Beispiel #5
0
const GAPopulation&
GASteadyStateGA::population(const GAPopulation& p) {
  if(p.size() < 1) {
    GAErr(GA_LOC, className(), "population", gaErrNoIndividuals);
    return *pop;
  }

  GAGeneticAlgorithm::population(p);
  delete tmpPop;

  if(which == USE_PREPL){
    double n = pRepl * pop->size();
    if(n < 1) n = 1.0;
    nRepl = (unsigned int)n;
    params.set(gaNnReplacement, nRepl);
  }
  else{
    if(nRepl > (unsigned int)(pop->size())) nRepl = pop->size();
    if(nRepl < 1) nRepl = 1;
  }
  tmpPop = new GAPopulation(pop->individual(0), nRepl);
  tmpPop->geneticAlgorithm(*this);

  return *pop;
}
Beispiel #6
0
// Resize the population.  If we shrink, we delete the extra genomes.  If
// we grow, we clone new ones (and we DO NOT initialize them!!!).  When we
// trash the genomes, we delete the worst of the population!  We do not
// free up the space used by the array of pointers, but we do free up the
// space used by the genomes.
//   We do a clone of the genome contents so that we don't have to initialize
// the new ones (what if the population has a custom initilizer?).  We randomly
// pick which ones to clone from the existing individuals.  If the population
// contains no genomes, then we post an error message (since there are no
// individuals from which to clone the new ones).
//   If the population was evaluated, then we evaluate the new genomes.  We
// do not sort nor restat the population, and we tag the statted and sorted
// flags to reflect the fact that they are no longer valid.
//   Resizing to a bigger size is the same as a batch 'add'
int
GAPopulation::size(unsigned int popsize){
  if(popsize == n) return n;
  if(n == 0 && popsize > 0) {
    GAErr(GA_LOC, "GAPopuluation", "size", gaErrNoIndividuals);
    return n;
  }

  if(popsize > n){
    grow(popsize);
    for(unsigned int i=n; i<popsize; i++)
      rind[i] = rind[GARandomInt(0,n-1)]->clone(GAGenome::CONTENTS);
    rsorted = gaFalse;
  }
  else{
    for(unsigned int i=popsize; i<n; i++) // trash the worst ones (if sorted)
      delete rind[i];			  // may not be sorted!!!!
  }

  memcpy(sind, rind, N * sizeof(GAGenome*));
  ssorted = scaled = statted = divved = selectready = gaFalse;
  n = popsize;  

  if(evaluated == gaTrue) evaluate(gaTrue);

  return n;
}
Beispiel #7
0
int
GA2DBinaryStringGenome::read(STD_ISTREAM & is)
{
  static char c;
  unsigned int i=0, j=0;
  while(!is.fail() && !is.eof() && j < ny) {
    is >> c;
    if(isdigit(c)){
      gene(i, j, ((c == '0') ? 0 : 1));
      if(++i >= nx){		// ready for next row
	i=0;
	j++;
      }
    }
  }

  _evaluated = gaFalse;

  if(is.eof() && 
     ((j < ny) ||	     // didn't get some lines
      (i < nx && i != 0))){   // stopped early on a row
    GAErr(GA_LOC, className(), "read", gaErrUnexpectedEOF);
    is.clear(STD_IOS_BADBIT | is.rdstate());
    return 1;
  }

  return 0;
}
Beispiel #8
0
/// Must do a special case for double/float.  Any floats that get passed to this
/// routine will be cast to doubles, but then we need to force them back to a
/// float if FLOAT is the type that is expected.  Kind of sucks, eh?
///   We could check the parameter type against the type here, but we don't.
/// (could do it for all of the 'set' members).  Maybe in a later release.
int
GAParameterList::set(const char* name, double v)
{
    int found = 0;
    for(unsigned int i = 0; i < n; i++)
    {
        if(strcmp(name, p[i]->fullname()) == 0 ||
                strcmp(name, p[i]->shrtname()) == 0)
        {
            if(p[i]->type() == GAParameter::FLOAT)
            {
                float fval = (float)v;
                p[i]->value((void*)&fval);
            }
            else if(p[i]->type() == GAParameter::DOUBLE)
            {
                p[i]->value((void*)&v);
            }
            else
            {
                GAErr(GA_LOC, "GAParameterList", "set", gaErrBadTypeIndicator);
            }
            found = 1;
        }
    }
    return found ? 0 : -1;
}
Beispiel #9
0
// Remove the specified node from the tree.  We don't cruise through the tree
// to make certain that the node is in the tree.  But we do check to make sure
// that the connections were ok before we prune the node.  If there is any
// problem with the links, we return a NULL.  If we get a NULL node, then we
// don't do anything.
//   We don't do anything to the next, prev, etc links of the node that is
// being removed (they are left pointing to where they used to point) so be
// careful!!
//   If the removal is on the root node, set the root node to NULL.
GANodeBASE *
GATreeBASE::remove(GANodeBASE * n)
{
  if(!n) return (GANodeBASE *)0;

  if(!n->next || !n->prev || n->prev->next != n || n->next->prev != n){
    GAErr(GA_LOC, "GATreeBASE", "remove", gaErrBadTreeLinks);
    return (GANodeBASE*)0;
  }

  if(n->next == n || !n->next){
    if(n->parent && n->parent->child == n)
      n->parent->child = (GANodeBASE *)0;
  }
  else{
    if(n->parent && n->parent->child == n)
      n->parent->child = n->next;
    n->prev->next = n->next;
    n->next->prev = n->prev;
  }

  if(n == rt) rt = (GANodeBASE *)0;

// uncomment these to modify the node that is getting removed
  n->prev = n;
  n->next = n;
  n->parent = 0;

  csz = 1;
  cdpth = 1;
  return n;
}
Beispiel #10
0
// Set the bits of the binary string based on the decimal value that is passed
// to us.  Notice that the number you pass may or may not be set properly.  It
// depends on the resolution defined in the phenotype.  If you didn't define 
// enough resolution, then there may be no way to represent the number.
//   We round off to the closest representable value, then return the number 
// that we actually entered (the rounded value).
// *** this is dangerous!  we're accessing the superclass' data representation
// directly, so if the representation changes to a bit stream, this will break.
//   If someone tries to set the phenotype beyond the bounds, we post an error
// then set the bits to the closer bound.
float
GABin2DecGenome::phenotype(unsigned int n, float val)
{
  if(n >= ptype->nPhenotypes()){
    GAErr(GA_LOC, className(), "phenotype", gaErrBadPhenotypeID);
    return val;
  }
  if(val < ptype->min(n) || val > ptype->max(n)){
    GAErr(GA_LOC, className(), "phenotype", gaErrBadPhenotypeValue);
    val = ((val < ptype->min(n)) ? ptype->min(n) : ptype->max(n));
  }
  encode(val,
	 &(data[ptype->offset(n)]), ptype->length(n),
	 ptype->min(n), ptype->max(n));
  return val;
}
Beispiel #11
0
int
GA3DBinaryStringGenome::read(std::istream & is)
{
  static char c;
  unsigned int i=0, j=0, k=0;
  do{
    is >> c;
    if(isdigit(c)){
      gene(i++, j, k, ((c == '0') ? 0 : 1));
      if(i >= nx){
	i=0;
	j++;
      }
      if(j >= ny){
	j=0;
	k++;
      }
    }
  } while(!is.fail() && !is.eof() && k < nz);

  _evaluated = gaFalse;

  if(is.eof() && 
     ((k < nz) ||		// didn't get some lines
      (j < ny && j != 0) ||	// didn't get some lines
      (i < nx && i != 0))){	// didn't get some lines
    GAErr(GA_LOC, className(), "read", gaErrUnexpectedEOF);
    is.clear(std::ios::badbit | is.rdstate());
    return 1;
  }

  return 0;
}
Beispiel #12
0
GABin2DecPhenotypeCore::~GABin2DecPhenotypeCore(){
  if(cnt > 0) 
    GAErr(GA_LOC, "GABin2DecPhenotypeCore", "destructor", gaErrRefsRemain);
  delete [] nbits;
  delete [] oset;
  delete [] minval;
  delete [] maxval;
}
Beispiel #13
0
const GAGenome & 
GAStatistics::bestIndividual(unsigned int n) const {
  if(boa == 0 || (int)n >= boa->size()){
    GAErr(GA_LOC, "GAStatistics", "bestIndividual", gaErrBadPopIndex);
    n = 0;
  }
  return boa->best(n);		// this will crash if no boa
}
Beispiel #14
0
// Set the multiplier for this selection type.  It should be greater than or
// equal to zero.
float
GASigmaTruncationScaling::multiplier(float fm) {
  if(fm < 0.0){
    GAErr(GA_LOC, className(), "multiplier", gaErrBadSigmaTruncationMult);
    return c;
  }
  return c = fm;
}
Beispiel #15
0
// The cutoff for triangular sharing must always be greater than 0
float
GASharing::sigma(float c) {
  if(c <= 0.0){
    GAErr(GA_LOC, className(), "sigma", gaErrBadSharingCutoff);
    return _sigma;
  }
  return _sigma = c;
}
Beispiel #16
0
// Set the multiplier for this selection type.  The fmultiplier must be greater
// than 1.0 or else we'll get a divide by zero error in our scaling operations.
float
GALinearScaling::multiplier(float fm) {
  if(fm <= 1.0){
    GAErr(GA_LOC, className(), "multiplier", gaErrBadLinearScalingMult);
    return c;
  }
  return c = fm;
}
Beispiel #17
0
GAAlleleSetCore<T>::~GAAlleleSetCore()
{
    if(cnt > 0)
    {
        GAErr(GA_LOC, "GAAlleleSetCore", "destructor", gaErrRefsRemain);
    }
    delete [] a;
}
Beispiel #18
0
// This is the class-specific copy method.  It will get called by the super
// class since the superclass operator= is set up to call ccopy (and that is
// what we define here - a virtual function).  We should check to be sure that
// both genomes are the same class.
void
BitStringGenome::copy(const GAGenome & orig) {
  if(&orig == this) return;
  if(!sameClass(orig)){
    GAErr(GA_LOC, className(), "copy", gaErrObjectTypeMismatch);
    return;
  }
  GAGenome::copy(orig);
  BitStringGenome &bsg = (BitStringGenome &)orig;
  BitString::operator=(bsg._substr(0,bsg.length()));
}
Beispiel #19
0
int
GAIncrementalGA::nOffspring(unsigned int value){
  if(value != 1 && value != 2){
    GAErr(GA_LOC, className(), "numCrossStrategy", gaErrBadCS);
    noffspr = 1;
  }
  else{
    noffspr = value;
  }
  params.set(gaNnOffspring, value);
  return noffspr;
}
Beispiel #20
0
GAIncrementalGA::ReplacementScheme
GAIncrementalGA::
replacement(GAIncrementalGA::ReplacementScheme n,
        GAIncrementalGA::ReplacementFunction f){
  switch(n){
  case BEST:
  case WORST:
  case RANDOM:
  case PARENT:
    rs = n;
    break;
  case CUSTOM:
    if(f){ rs = n; rf = f; }
    else GAErr(GA_LOC, className(), "replacement", gaErrNeedRS);
    break;
  default:
    GAErr(GA_LOC, className(), "replacement", gaErrBadRS);
    break;
  }
  return rs;
}
Beispiel #21
0
const GAPopulation&
GAGeneticAlgorithm::population(const GAPopulation& p) {
  if(p.size() < 1) {
    GAErr(GA_LOC, className(), "population", gaErrNoIndividuals);
    return *pop;
  }
  
  pop->copy(p);
  pop->geneticAlgorithm(*this);

  return *pop;
}
Beispiel #22
0
// Do some basic stupidity checks then initialize the population.  We must
// also initialize our temporary genomes, but we don't have to evaluate
// them.  Finally, reset the statistics.
void
GAIncrementalGA::initialize(unsigned int seed)
{
  GARandomSeed(seed);

  pop->initialize();
  pop->evaluate(gaTrue);

  stats.reset(*pop);

  if(!scross) GAErr(GA_LOC, className(), "initialize", gaErrNoSexualMating);
}
Beispiel #23
0
int
GAParameterList::write(const char* filename) const {
  STD_OFSTREAM outfile(filename, (STD_IOS_OUT | STD_IOS_TRUNC));
// should be done this way, but SGI systems (and others?) don't do it right...
//  if(! outfile.is_open()){
  if(outfile.fail()){
    GAErr(GA_LOC, "GAParameterList", "write", gaErrWriteError, filename);
    return 1;
  }
  int status = write(outfile);
  outfile.close();
  return status;
}
Beispiel #24
0
// You can specify the data that you want to dump out when you call this
// routine, or you can just let it use the selection from the object.  If you
// specify a data set, that will be used rather than the 'which' in the object.
int 
GAStatistics::scores(const char* filename, int w){
  STD_OFSTREAM outfile(filename, (STD_IOS_OUT | STD_IOS_TRUNC));
// should be done this way, but SGI systems (and others?) don't do it right...
//  if(! outfile.is_open()){
  if(outfile.fail()){
    GAErr(GA_LOC, "GAStatistics", "scores", gaErrWriteError, filename);
    return 1;
  }
  scores(outfile, w);
  outfile.close();
  return 0;
}
Beispiel #25
0
int
GAParameterList::write(const char* filename) const {
  std::ofstream outfile(filename, (std::ios::out | std::ios::trunc));
// should be done this way, but SGI systems (and others?) don't do it right...
//  if(! outfile.is_open()){
  if(outfile.fail()){
    GAErr(GA_LOC, "GAParameterList", "write", gaErrWriteError, filename);
    return 1;
  }
  int status = write(outfile);
  outfile.close();
  return status;
}
Beispiel #26
0
// We access the data string directly here.  This could be dangerous (if the
// bitstream ever changes on us it will affect the way this method sees the
// data string).
//   Eventually we may need to cache the decimal values in an array of floats,
// but for now we call the converter routine every time each phenotype is 
// requested.
float
GABin2DecGenome::phenotype(unsigned int n) const
{
  if(n >= ptype->nPhenotypes()){
    GAErr(GA_LOC, className(), "phenotype", gaErrBadPhenotypeID);
    return(0.0);
  }
  float val=0.0;
  decode(val,
	 &(data[ptype->offset(n)]), ptype->length(n), 
	 ptype->min(n), ptype->max(n));
  return val;
}
//   Set the resize behaviour of the genome.  A genome can be fixed
// length, resizeable with a max and min limit, or resizeable with no limits
// (other than an implicit one that we use internally).
//   A value of 0 means no resize, a value less than zero mean unlimited 
// resize, and a positive value means resize with that value as the limit.
//   We return the upper limit of the genome's size.
int
GA1DBinaryStringGenome::
resizeBehaviour(unsigned int lower, unsigned int upper)
{
  if(upper < lower){
    GAErr(GA_LOC, className(), "resizeBehaviour", gaErrBadResizeBehaviour);
    return resizeBehaviour();
  }
  minX = lower; maxX = upper;
  if(nx > upper) resize(upper);
  if(nx < lower) resize(lower);
  return resizeBehaviour();
}
Beispiel #28
0
int
GADemeGA::populationSize(int i, unsigned int value){
  if(value < 1){
    GAErr(GA_LOC, className(), "populationSize", gaErrBadPopSize);
    value = 1;
  }
  if(i == ALL)
    for(unsigned int ii=0; ii<npop; ii++)
      deme[ii]->size(value);
  else
    deme[i]->size(value);
  return value;
}
Beispiel #29
0
// 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!
  }
}
//   Set the resize behaviour of the genome.  A genome can be fixed
// length, resizeable with a max and min limit, or resizeable with no limits
// (other than an implicit one that we use internally).
//   A value of 0 means no resize, a value less than zero mean unlimited
// resize, and a positive value means resize with that value as the limit.
template <class T> int
GA1DArrayGenome<T>::
resizeBehaviour(unsigned int lower, unsigned int upper)
{
    if(upper < lower) {
        GAErr(GA_LOC, className(), "resizeBehaviour", gaErrBadResizeBehaviour);
        return resizeBehaviour();
    }
    minX = lower;
    maxX = upper;
    if(nx > upper) GA1DArrayGenome<T>::resize(upper);
    if(nx < lower) GA1DArrayGenome<T>::resize(lower);
    return resizeBehaviour();
}