C++ genetic algorithm class file example analysis
- 2020-04-02 02:34:07
- OfStack
This article describes a class file example of the genetic algorithm implemented in C++. Generally speaking, genetic algorithm can solve many problems, I hope the C++ genetic algorithm class file described in this article, can help you solve more problems, and the code in order to facilitate a better understanding of the reader, and added rich annotation content, is a novice to learn genetic algorithm rare reference code.
The specific code is as follows:
#include "stdafx.h"
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>//Converts the date and time to a string
using namespace std;
//Parametes setting
#define POPSIZE 200 //population size
#define MAXGENS 1000 //max number of generation
#define NVARS 2 //no of problem variables
#define PXOVER 0.75 //probalility of crossover
#define PMUTATION 0.15 //probalility of mutation
#define TRUE 1
#define FALSE 0
#define LBOUND 0
#define UBOUND 12
#define STOP 0.001
int generation; //current generation no
int cur_best; //best individual
double diff;
FILE *galog; //an output file
struct genotype
{
double gene[NVARS]; //A string of variables
double upper[NVARS]; //Individual's variables are upper bound
double lower[NVARS]; //Individual's batiables lower bound
double fitness; //Individual's fitness value
double rfitness; //Relative fitness ratio of individual fitness value to population fitness value
double cfitness; //Curmulation of the cumulative proportion of individual fitness values
};
struct genotype population[POPSIZE+1];
//Population current population[POPSIZE] is used to store the optimal value of an individual and to assume that the optimal individual can survive
//In some genetic algorithms, the optimal value of an individual does not necessarily survive
struct genotype newpopulation[POPSIZE+1]; //The new population replaces the old generation populations
void initialize(void); //Initialization function
double randval(double,double); //Random function
double funtion(double x1,double x2); //The objective function
void evaluate(void); //Evaluation function
void keep_the_best(void); //Keep the best individuals
void elitist(void); //The optimal value of current population and offspring population is compared
void select(void);
void crossover(void); //Recombination function
void swap(double *,double *); //Exchange function
void mutate(void); //Mutation function
double report(void); //Data recording function
void initialize(void)
{
int i,j;
for(i=0;i<NVARS;i++)
{
for(j=0;j<POPSIZE+1;j++)
{
if(!i)
{
population[j].fitness=0;
population[j].rfitness=0;
population[j].cfitness=0;
}
population[j].lower[i]=LBOUND;
population[j].upper[i]=UBOUND;
population[j].gene[i]=randval(population[j].lower[i],population[j].upper[i]);
}
}
}
//***************************************************************************
//Random value generator:generates a value within bounds
//***************************************************************************
double randval(double low,double high)
{
double val;
val=((double)(rand()%10000)/10000)*(high-low)+low;
return val;
}
//The objective function
double funtion(double x,double y)
{
double result1=sqrt(x*x+y*y)+sqrt((x-12)*(x-12)+y*y)+sqrt((x-8)*(x-8)+(y-6)*(y-6));
return result1;
}
//***************************************************************************
//Evaluation function:evaluate the individual's fitness.Evaluation function Give the individual To adapt to the value
//Each time the function is changes,the code has to be recompl
//***************************************************************************
void evaluate(void)
{
int mem;
int i;
double x[NVARS];
for(mem=0;mem<POPSIZE;mem++)
{
for(i=0;i<NVARS;i++)
x[i]=population[mem].gene[i];
population[mem].fitness=funtion(x[0],x[1]);// will The objective function Value as To adapt to the value
}
}
//***************************************************************************************
//Keep_the_best function:This function keeps track of the best member of the population.
//Find the individual optimal value in the population and move it to the end
//***************************************************************************************
void keep_the_best()
{
int mem;
int i;
cur_best=0;
for(mem=0;mem<POPSIZE;mem++)//Identify the individuals with the highest fitness values
{
if(population[mem].fitness<population[cur_best].fitness)
{
cur_best=mem;
}
}
//Copy the optimal individuals to population[POSIZE]
if(population[cur_best].fitness<=population[POPSIZE].fitness||population[POPSIZE].fitness<1)//Historically optimal individuals were retained to prevent genetic degradation of the population
{
population[POPSIZE].fitness=population[cur_best].fitness;
for(i=0;i<NVARS;i++)
population[POPSIZE].gene[i]=population[cur_best].gene[i];
}
}
//***************************************************************************
//last in the array.If the best individual from the new populatin is better
//than the best individual from the previous population ,then copy the best
//from the new population;else replace the worst individual from the current
//Population with the best one from the previous generation
//***************************************************************************
void elitist()
{
int i;
double best,worst;//To adapt to the value
int best_mem,worst_mem;//The serial number
best_mem=worst_mem=0;
best=population[best_mem].fitness;// The highest To adapt to the value Initialize the
worst=population[worst_mem].fitness;// The minimum To adapt to the value Initialize the
for(i=1;i<POPSIZE;i++)// Find the highest and lowest To adapt to the value Algorithm to be improved
{
if(population[i].fitness<best)
{
best=population[i].fitness;
best_mem=i;
}
if(population[i].fitness>worst)
{
worst=population[i].fitness;
worst_mem=i;
}
}
if(best<=population[POPSIZE].fitness)//The assignment
{
for(i=0;i<NVARS;i++)
population[POPSIZE].gene[i]=population[best_mem].gene[i];
population[POPSIZE].fitness=population[best_mem].fitness;
}
else
{
for(i=0;i<NVARS;i++)
population[worst_mem].gene[i]=population[POPSIZE].gene[i];
population[worst_mem].fitness=population[POPSIZE].fitness;
}
}
//***************************************************************************
//Select function:Standard proportional selection for maximization problems
//Incorporating elitist model, top service sure that the best member survives. The filter function and produce offspring
//***************************************************************************
void select(void)
{
int mem,i,j;
double sum=0;
double p;
for(mem=0;mem<POPSIZE;mem++)// all To adapt to the value sum
{
sum+=population[mem].fitness;
}
for(mem=0;mem<POPSIZE;mem++)
{
population[mem].rfitness=population[mem].fitness/sum;//I think it's better to build a population class and treat sum as a member of the class
}
population[0].cfitness=population[0].rfitness;
for(mem=1;mem<POPSIZE;mem++)
{
population[mem].cfitness=population[mem-1].cfitness+population[mem].rfitness;
}
for(i=0;i<POPSIZE;i++)
{
p=rand()%1000/1000.0;
if(p<population[0].cfitness)
{
newpopulation[i]=population[0];
}
else
{
for(j=0;j<POPSIZE;j++)
if(p>=population[j].cfitness&&p<population[j+1].cfitness)
newpopulation[i]=population[j+1];
}
}
for(i=0;i<POPSIZE;i++)//Children become parents
population[i]=newpopulation[i];
}
//***************************************************************************
//Crossover:performs crossover of the selected parents.
//***************************************************************************
void Xover(int one,int two)//Recombination function
{
int i;
int point;
if(NVARS>1)
{
if(NVARS==2)
point=1;
else
point=(rand()%(NVARS-1))+1;//Recombination of both?
for(i=0;i<point;i++)//Only the first gene was reprogrammed for improvement
swap(&population[one].gene[i],&population[two].gene[i]);
}
}
//***************************************************************************
//Swapp: a swap procedure the helps in swappling 2 variables
//***************************************************************************
void swap(double *x,double *y)
{
double temp;
temp=*x;
*x=*y;
*y=temp;
}
//***************************************************************************
//Crossover function:select two parents that take part in the crossover.
//Implements a single point corssover. Cross function
//***************************************************************************
void crossover(void)
{
int mem,one;
int first=0;
double x;
for(mem=0;mem<POPSIZE;++mem)
{
x=rand()%1000/1000.0;
if(x<PXOVER)
{
++first;
if(first%2==0)//The individuals who choose to hybridize have to improve on the hybridization and in fact it is often the strong hybrid with the strong hybrid and there is no consideration of the choice between male and female and the object of the hybrid
Xover(one,mem);
else
one=mem;
}
}
}
//***************************************************************************
//Mutation function:Random uniform mutation.a variable selected for mutation
//The function of variation is the fact that genetic variation tends to be localized
//is replaced by a random value between lower and upper bounds of the variables.
//***************************************************************************
void mutate(void)
{
int i,j;
double lbound,hbound;
double x;
for(i=0;i<POPSIZE;i++)
for(j=0;j<NVARS;j++)
{
x=rand()%1000/1000.0;
if(x<PMUTATION)
{
lbound=population[i].lower[j];
hbound=population[i].upper[j];
population[i].gene[j]=randval(lbound,hbound);
}
}
}
//***************************************************************************
//Report function:Reports progress of the simulation.
//***************************************************************************
double report(void)
{
int i;
double best_val;// Intra-population optimality To adapt to the value
double avg;// The average individual To adapt to the value
//double stddev;
double sum_square;// in-population To adapt to the value Sum of squares
//double square_sum;
double sum;// population To adapt to the value
sum=0.0;
sum_square=0.0;
for(i=0;i<POPSIZE;i++)
{
sum+=population[i].fitness;
sum_square+=population[i].fitness*population[i].fitness;
}
avg=sum/(double)POPSIZE;
//square_sum=avg*avg*(double)POPSIZE;
//stddev=sqrt((sum_square-square_sum)/(POPSIZE-1));
best_val=population[POPSIZE].fitness;
fprintf(galog,"%6d %6.3f %6.3f %6.3f %6.3f %6.3fn",generation,best_val,population[POPSIZE].gene[0],population[POPSIZE].gene[1],avg,sum);
return avg;
}
//***************************************************************************
//main function:Each generation involves selecting the best members,performing
//crossover & mutation and then evaluating the resulting population,until the
//terminating condition is satisfied.
//***************************************************************************
void main(void)
{
int i;
double temp;
double temp1;
if((galog=fopen("data.txt","w"))==NULL)
{
exit(1);
}
generation=1;
srand(time(NULL));//Generate random number
fprintf(galog,"number value x1 x2 avg sum_valuen");
printf("generation best average standardn");
initialize();
evaluate();
keep_the_best();
temp=report();// record , Temporarily store the previous generation's individual average To adapt to the value
do
{
select();//screening
crossover();//The hybrid
mutate();//variation
evaluate();//evaluation
keep_the_best();//elitist();
temp1=report();
diff=fabs(temp-temp1);//Find the absolute value of floating point number x
temp=temp1;
generation++;
}while(generation<MAXGENS&&diff>=STOP);
//fprintf(galog,"nn Simulation completedn");
//fprintf(galog,"n Best member:n");
printf("nBest member:ngeneration:%dn",generation);
for(i=0;i<NVARS;i++)
{
//fprintf(galog,"n var(%d)=%3.3f",i,population[POPSIZE].gene[i]);
printf("X%d=%3.3fn",i,population[POPSIZE].gene[i]);
}
//fprintf(galog,"nn Best fitness=%3.3f",population[POPSIZE].fitness);
fclose(galog);
printf("nBest fitness=%3.3fn",population[POPSIZE].fitness);
}
Interested readers can test the code, I hope to help you learn C++ algorithm.