Listing 3 More member functions of class CGAChromosome

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include "chrom.h"

size_t    CGAChromosome::m_Count         = 0;
size_t    CGAChromosome::m_Length        = 0;
GABool*   CGAChromosome::m_CrossoverMask = 0;

// Default constructor and destructor.
// Create the chromosome with bits turned on at the
// given probability.

CGAChromosome::CGAChromosome(
   float Prob)
{
   assert(m_Length);
   m_Fitness  = 0;
   m_Data     = new GABool[m_Length];
   assert(m_Data);
   m_Count++;
   for (size_t Idx = 0; Idx < m_Length; Idx++) {
      m_Data[Idx] = Flip(Prob);
   }
   m_Fitness = CalcFitness(this);
}

CGAChromosome::~CGAChromosome(void)
{
  delete[] m_Data;
   if (--m_Count == 0) {
      delete[] m_CrossoverMask;
      m_Length        = 0;
      m_CrossoverMask = 0;
   }
}

// Mutate a single chromosome gene selected at
// random for a given probability.

void CGAChromosome::Mutate(
   float Prob)
{
   for (size_t Idx = 0; Idx < m_Length; Idx++) {
      if (Flip(Prob)) {
         m_Data[Idx] = !m_Data[Idx];
      }
   }
}

// Create two new offspring using a uniform crossover
// operator created with the given probability.

void Crossover(
   CGAChromosome* Parent1,
   CGAChromosome* Parent2,
   CGAChromosome*& Child1,
   CGAChromosome*& Child2,
   float Prob)
{
   CGAChromosome::InitializeCrossoverMask(0.5);
   Child1 = new CGAChromosome();
   Child2 = new CGAChromosome();
   assert(Child1 && Child2);

   for (size_t Idx = 0; Idx < CGAChromosome::m_Length;
       Idx++) {
     if (CGAChromosome::m_CrossoverMask[Idx]) {
        Child1->m_Data[Idx] = Parent1->m_Data[Idx];
        Child2->m_Data[Idx] = Parent2->m_Data[Idx];
     } else {
        Child1->m_Data[Idx] = Parent2->m_Data[Idx];
        Child2->m_Data[Idx] = Parent1->m_Data[Idx];
     }
   }
   Child1->Mutate(Prob);
   Child2->Mutate(Prob);
   Child1->m_Fitness = CalcFitness(Child1);
   Child2->m_Fitness = CalcFitness(Child2);
}

// Calculate the difference between two chromosomes

float CalcSimilarityRatio(
   CGAChromosome* Chrom1,
   CGAChromosome* Chrom2)
{
   for (size_t Idx = 0, MatchCount = 0;
       Idx < CGAChromosome::m_Length; Idx++) {
     if (Chrom1->m_Data[Idx] == Chrom2->m_Data[Idx]) {
        MatchCount++;
     }
   }
   return (float)MatchCount /
         (float)CGAChromosome::m_Length;
}

// Set the new chromosome to the opposite encoding
// of this chromosome.

CGAChromosome* CGAChromosome::complement(void) const
{
   CGAChromosome* Chromosome = new CGAChromosome;
   for (size_t Idx = 0; Idx < m_Length; Idx++) {
     Chromosome->m_Data[Idx] = !m_Data[Idx];
   }
   Chromosome->m_Fitness = CalcFitness(Chromosome);
   return Chromosome;
}

// Setup the crossover mask for creating the next
// offspring.

void CGAChromosome::InitializeCrossoverMask(
   float Prob)
{
   assert(m_Length && m_CrossoverMask);
   for (size_t Idx = 0; Idx < m_Length; Idx++) {
     m_CrossoverMask[Idx] = Flip(Prob);
   }
}

// Setup the chromosomes' length and allocate memory
// for the crossover mask.

void CGAChromosome::InitializeChromosomeClass(
   size_t Length)
{
   assert(Length);
   m_Length = Length;
   if (m_Count) != 0) {
     delete [] m_CrossoverMask;
   }
   m_CrossoverMask = new GaBool[m_Length];
   assert(m_CrossoverMask);
}
/* End of File */