📄 cpbil.cpp
字号:
//GAPBILExample
//Copyright John Manslow
//29/09/2001
////////////////////////////////////////////////////
//Remove this include if not compiling under Windows
#include "stdafx.h"
#define new DEBUG_NEW
////////////////////////////////////////////////////
#include "CPBIL.h"
#include "assert.h"
#include "fstream.h"
CPBIL::CPBIL(
const unsigned long ulNewPopulationSize,
const unsigned long ulNewChromosomeLength
)
{
//Check validity of arguments
assert(!(ulNewPopulationSize<1));
ulPopulationSize=ulNewPopulationSize;
assert(!(ulNewChromosomeLength<1));
ulChromosomeLength=ulNewChromosomeLength;
//Set default mutation and adaptation rates
dMutationRate=0.01/double(ulChromosomeLength);
dAdaptationRate=0.1;
//Reset the fitness evaluation counter
ulIteration=0;
//Allocate memory to store the population
AllocateMemory();
}
CPBIL::~CPBIL()
{
//Clean up
DeallocateMemory();
}
void CPBIL::AllocateMemory(void)
{
unsigned long i;
//Create storage for the population
ppdGenes=new double*[ulPopulationSize];
for (i=0;i<ulPopulationSize;i++)
{
ppdGenes[i]=new double[ulChromosomeLength];
}
//And for the fitnesses of the chromosomes within it
pdFitnesses=new double[ulPopulationSize];
//Create storage for the gene probability vector
pdGeneProbabilities=new double[ulChromosomeLength];
//Set gene probabilities to 0.5 so that initially, each gene is equally likely to be 0 or 1
for (i=0;i<ulChromosomeLength;i++)
{
pdGeneProbabilities[i]=0.5;
}
//Declare stoarge for a copy of the best chromosome discovered so far and set its fitness to a large
//negative number so that it'll be overwritten immediately
pdBestChromosome=new double[ulChromosomeLength];
dBestFitness=-1e+100;
}
void CPBIL::DeallocateMemory(void)
{
unsigned long i;
delete []pdFitnesses;
for (i=0;i<ulPopulationSize;i++)
{
delete []ppdGenes[i];
}
delete []ppdGenes;
delete []pdGeneProbabilities;
delete []pdBestChromosome;
}
void CPBIL::CreatePopulation(void)
{
//This function is called to create a population of chromosomes by sampling form the probability distribution
//given in pdGeneProbabilities.
unsigned long i,j;
//For each chromosome in the population
for (i=0;i<ulPopulationSize;i++)
{
//Reset its fitness
pdFitnesses[i]=0.0;
//For each gene in the ith chromosome
for (j=0;j<ulChromosomeLength;j++)
{
//Set the gene to either 0 or 1 in accordance with the gene probability vector
if(double(rand())/double(RAND_MAX)>pdGeneProbabilities[j])
{
ppdGenes[i][j]=0.0;
}
else
{
ppdGenes[i][j]=1.0;
}
}
}
}
void CPBIL::Mutate(void)
{
//The mutate function resets a randomly selected element of the gene probability vector to 0.5. Mutation
//can usually be removed with the PBIL - provded that its population size is large and rate of adaptation is
//small. Mutation should have a much lower probability than in the GA
unsigned long i;
for (i=0;i<ulChromosomeLength;i++)
{
if(double(rand())/double(RAND_MAX)<dMutationRate)
{
pdGeneProbabilities[i]=0.5;
}
}
}
double *CPBIL::pdGetChromosomeForEvaluation(void)
{
//This function automatically selects each chromosome in the population, and once
//all have been evaluated, creates a new population
unsigned long i;
//ff the chromosome selector (i.e. ulIteration%ulPopulationSize) indicates the first chromosome in the
//population needs to be evaluted, a new population needs to be created
if (ulIteration%ulPopulationSize==0)
{
CreatePopulation();
}
//Set the working chromosome to the location of the chromosome in the population so that when SetFitness
//is called, we know which chromosome it refers to
ulWorkingChromosome=ulIteration%ulPopulationSize;
//Create space for a copy of the chromosome that needs to be evaluated
double *pdChromosomeForEvaluation=new double[ulChromosomeLength];
for (i=0;i<ulChromosomeLength;i++)
{
//Copy the genes into it
pdChromosomeForEvaluation[i]=ppdGenes[ulWorkingChromosome][i];
}
//Return it to the clling function
return pdChromosomeForEvaluation;
}
void CPBIL::SetFitness(const double dNewFitness)
{
//This function records the ftiness of the chromosome that has just beenevaluated. If the chromosome
//selector (i.e. ulIteration%ulPopulationSize) has wrapped around to the start of the population, we have
//evaluated the fitnesses of every individual in the population and hence can update the gene probability
//vector.
unsigned long i;
double dHighestFitness=0.0;
unsigned long ulFittestChromosome=0;
//Increment the counter of the number of fitness evaluations
ulIteration++;
//Record the fitness
pdFitnesses[ulWorkingChromosome]=dNewFitness;
//If its the best discovered so far take a copy of it
if(dNewFitness>dBestFitness)
{
dBestFitness=dNewFitness;
unsigned long i;
for(i=0;i<ulChromosomeLength;i++)
{
pdBestChromosome[i]=ppdGenes[ulWorkingChromosome][i];
}
}
//If the chromosome selector has wrapped around to the start of the population
if(ulIteration%ulPopulationSize==0)
{
//Find the fittest chromosome in the population
for(i=0;i<ulPopulationSize;i++)
{
if(pdFitnesses[i]>dHighestFitness)
{
dHighestFitness=pdFitnesses[i];
ulFittestChromosome=i;
}
}
//Update the gene probabilities by changing them to increase the chance that the best chromosome in
//this population is reproduced more frequenctly in future
for(i=0;i<ulChromosomeLength;i++)
{
pdGeneProbabilities[i]+=dAdaptationRate*(ppdGenes[ulFittestChromosome][i]-pdGeneProbabilities[i]);
}
//Mutate the probability vector
Mutate();
}
}
double *CPBIL::pdGetBestChromosome(void)
{
//Return a pointer to the best chromosome. Its not a copy, so don't delete it!
return pdBestChromosome;
}
double CPBIL::dGetBestPerformance(void)
{
//Return the best fitness achieved so far
return dBestFitness;
}
int CPBIL::Save(const char * const psFilename)
{
//Save the PBIL's status
ofstream *pOut=new ofstream(psFilename);
unsigned long i,j;
if(!pOut || !pOut->is_open())
{
return 0;
}
pOut->precision(18);
*pOut<<ulPopulationSize;
*pOut<<"\n";
*pOut<<ulChromosomeLength;
*pOut<<"\n";
*pOut<<dMutationRate;
*pOut<<"\n";
*pOut<<ulIteration;
*pOut<<"\n";
*pOut<<ulWorkingChromosome;
*pOut<<"\n";
for (i=0;i<ulPopulationSize;i++)
{
for (j=0;j<ulChromosomeLength;j++)
{
*pOut<<ppdGenes[i][j];
*pOut<<"\t";
}
*pOut<<pdFitnesses[i];
*pOut<<"\n";
}
for (i=0;i<ulChromosomeLength;i++)
{
*pOut<<pdGeneProbabilities[i];
*pOut<<"\t";
}
*pOut<<"\n";
*pOut<<dBestFitness;
*pOut<<"\n";
for (j=0;j<ulChromosomeLength;j++)
{
*pOut<<pdBestChromosome[j];
*pOut<<"\t";
}
*pOut<<"\n";
pOut->close();
delete pOut;
return 1;
}
int CPBIL::Load(const char * const psFilename)
{
//Load the PBIL's status
ifstream *pIn=new ifstream(psFilename,ios::nocreate);
unsigned long i,j;
if(!pIn || !pIn->is_open())
{
return 0;
}
DeallocateMemory();
*pIn>>ulPopulationSize;
*pIn>>ulChromosomeLength;
AllocateMemory();
*pIn>>dMutationRate;
*pIn>>ulIteration;
*pIn>>ulWorkingChromosome;
for (i=0;i<ulPopulationSize;i++)
{
for (j=0;j<ulChromosomeLength;j++)
{
*pIn>>ppdGenes[i][j];
}
*pIn>>pdFitnesses[i];
}
for (i=0;i<ulChromosomeLength;i++)
{
*pIn>>pdGeneProbabilities[i];
}
*pIn>>dBestFitness;
for (j=0;j<ulChromosomeLength;j++)
{
*pIn>>pdBestChromosome[j];
}
pIn->close();
delete pIn;
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -