📄 prog.cpp
字号:
/***************************************************************//* This is a simple genetic algorithm implementation where the *//* evaluation function takes positive values only and the *//* fitness of an individual is the same as the value of the *//* objective function *//***************************************************************/#include <stdio.h>#include <stdlib.h>#include <math.h>#include <time.h>/* Change any of these parameters to match your needs */#define TRUE 1#define FALSE 0#define POPSIZE 100 /* population size */#define MAXGENS 1000 /* max. number of generations */#define NVARS 2 /* no. of problem variables */#define PI 3.14159#define PXOVER 0.8 /* probability of crossover */#define PMUTATION 0.001 /* probability of mutation */int generation; /* current generation no. */int cur_best; /* best individual */FILE *galog; /* an output(1) file */FILE *output; /* an output(1) file */struct genotype /* genotype (GT), a member of the population */{ double gene[NVARS]; /* a string of variables */ double fitness; /* GT's fitness */ double upper[NVARS]; /* GT's variables upper bound */ double lower[NVARS]; /* GT's variables lower bound */ double rfitness; /* relative fitness */ double cfitness; /* cumulative fitness */};struct genotype population[POPSIZE+1]; /* population */struct genotype newpopulation[POPSIZE+1]; /* new population; */ /* replaces the */ /* old generation *//* Declaration of procedures used by this genetic algorithm */void initialize(void);double randval(double, double);void evaluate(void);void keep_the_best(void);void elitist(void);void select(void);void crossover(void);void Xover(int,int);void swap(double *, double *);void mutate(void);void report(void);/***************************************************************//* Initialization function: Initializes the values of genes *//* within the variables bounds. It also initializes (to zero) *//* all fitness values for each member of the population. It *//* reads upper and lower bounds of each variable from the *//* input file `gadata.txt'. It randomly generates values *//* between these bounds for each gene of each genotype in the *//* population. The format of the input file `gadata.txt' is *//* var1_lower_bound var1_upper bound *//* var2_lower_bound var2_upper bound ... *//***************************************************************/void initialize(void){FILE *infile;int i, j;double lbound, ubound;if ((infile = fopen("gadata.txt","r"))==NULL) { fprintf(galog,"\nCannot open input file!\n"); exit(1); }remove("output.dat");/* initialize variables within the bounds */for (i = 0; i < NVARS; i++) { // change the format of the data input 2007-9-27 fscanf(infile, "%lf\t",&lbound); fscanf(infile, "%lf\n",&ubound); //printf("\nlbound:%lf\t\tubound:%lf",lbound,ubound); getchar(); for (j = 0; j < POPSIZE; j++) { 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]); } }fclose(infile);}/***********************************************************//* Random value generator: Generates a value within bounds *//***********************************************************/double randval(double low, double high){double val;//srand(time(NULL));val = ((double)(rand()%1000)/1000.0)*(high - low) + low;return(val);}/*************************************************************//* Evaluation function: This takes a user defined function. *//* Each time this is changed, the code has to be recompiled. *//* The current function is: x[1]^2-x[1]*x[2]+x[3] *//*************************************************************/void evaluate(void){//if ((output = fopen("output.dat","a"))==NULL)// {// exit(1);// }int mem;int i;double x[NVARS+1]; for (mem = 0; mem < POPSIZE; mem++) { for (i = 0; i < NVARS; i++) x[i+1] = population[mem].gene[i]; population[mem].fitness = 21.5+x[1]*sin(4*PI*x[1])+x[2]*sin(20*PI*x[2]);//x[1]*sin(10.0*3.14*x[1])+1.0;//x[1]*x[1]+x[2]*x[2]; if (population[mem].fitness <40 && population[mem].fitness>35) { fprintf(output, "\n%5d, %6.9f, %6.9f, %6.9f ", generation, x[1],x[2],population[mem].fitness); } }}/***************************************************************//* Keep_the_best function: This function keeps track of the *//* best member of the population. Note that the last entry in *//* the array Population holds a copy of the best individual *//***************************************************************/void keep_the_best(){int mem;int i;cur_best = 0; /* stores the index of the best individual */for (mem = 0; mem < POPSIZE; mem++) { if (population[mem].fitness > population[POPSIZE].fitness) { cur_best = mem; population[POPSIZE].fitness = population[mem].fitness; } }/* once the best member in the population is found, copy the genes */for (i = 0; i < NVARS; i++) population[POPSIZE].gene[i] = population[cur_best].gene[i];}/****************************************************************//* Elitist function: The best member of the previous generation *//* is stored as the last in the array. If the best member of *//* the current generation is worse then the best member of the *//* previous generation, the latter one would replace the worst *//* member of the current population *//****************************************************************/void elitist(){int i;double best, worst; /* best and worst fitness values */int best_mem, worst_mem; /* indexes of the best and worst member */best = population[0].fitness;worst = population[0].fitness;for (i = 0; i < POPSIZE - 1; ++i) { if(population[i].fitness > population[i+1].fitness) { if (population[i].fitness >= best) { best = population[i].fitness; best_mem = i; } if (population[i+1].fitness <= worst) { worst = population[i+1].fitness; worst_mem = i + 1; } } else { if (population[i].fitness <= worst) { worst = population[i].fitness; worst_mem = i; } if (population[i+1].fitness >= best) { best = population[i+1].fitness; best_mem = i + 1; } } }/* if best individual from the new population 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 */if (best >= population[POPSIZE].fitness) { 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; } }/**************************************************************//* Selection function: Standard proportional selection for *//* maximization problems incorporating elitist model - makes *//* sure that the best member survives *//**************************************************************/// sort the fitness of population from small to largervoid bubble_sort(int *(pos[])){ int i=0,j=0,flag=0,k=0,temp=0; j=POPSIZE-2; flag=0; //flag=0表示排序完成,flag=1表示记录有序,无须进行比较 k=POPSIZE-1; while(flag==0&&j>=0) { flag=1; for(i=0;i<=j;i++) { if(population[ (*pos)[i] ].fitness > population[ (*pos)[i+1] ].fitness ) { temp=(*pos)[i]; (*pos)[i]=(*pos)[i+1]; (*pos)[i+1]=temp; flag=0; k=i; } j=k-1; } }}// 排序选择void select_ranking(void){ int i=0,j=0; double p=0; int* pos=(int*)malloc(POPSIZE*sizeof(int)); //记录适应度大小排序后的位置,由小至大 for(i=0;i<POPSIZE;i++) pos[i]=i; bubble_sort(&pos); for (i = 0; i < POPSIZE; i++) { population[i].rfitness = 2.0*(double)(pos[i]+1)/(POPSIZE*(POPSIZE+1)); } population[0].cfitness = population[0].rfitness; /* calculate cumulative fitness */ for (i = 1; i < POPSIZE; i++) { population[i].cfitness = population[i-1].cfitness + population[i].rfitness; } /* finally select survivors using cumulative fitness. */ 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]; } } /* once a new population is created, copy it back */ for (i = 0; i < POPSIZE; i++) population[i] = newpopulation[i]; }// 轮盘赌void select(void){int mem, i, j;double sum = 0;double p;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -