#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 */