home *** CD-ROM | disk | FTP | other *** search
- #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 passed chromosome to the opposite encoding
- // of this chromosome.
-
- CGAChromosome* CGAChromosome::Compliment(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);
- }
-