// GA.cpp : Defines the entry point for the console application.///*这是一个非常简单的遗传算法源代码,是由Denis Cormier (North Carolina State University)开发的,Sita S.Raghavan (University of North Carolina at Charlotte)修正。
代码保证尽可能少,实际上也不必查错。
对一特定的应用修正此代码,用户只需改变常数的定义并且定义“评价函数”即可。
注意代码的设计是求最大值,其中的目标函数只能取正值;且函数值和个体的适应值之间没有区别。
该系统使用比率选择、精华模型、单点杂交和均匀变异。
如果用Gaussian变异替换均匀变异,可能得到更好的效果。
代码没有任何图形,甚至也没有屏幕输出,主要是保证在平台之间的高可移植性。
读者可以从, 目录coe/evol中的文件prog.c中获得。
要求输入的文件应该命名为‘gadata.txt’;系统产生的输出文件为‘galog.txt’。
输入的文件由几行组成:数目对应于变量数。
且每一行提供次序——对应于变量的上下界。
如第一行为第一个变量提供上下界,第二行为第二个变量提供上下界,等等。
*/#include <stdio.h>#include <stdlib.h>#include <math.h>/* Change any of these parameters to match your needs *///请根据你的需要来修改以下参数#define POPSIZE 50 /* population size 种群大小*/#define MAXGENS 1000 /* max. number of generations 最大基因个数*/const int NVARS = 3; /* no. of problem variables 问题变量的个数*/#define PXOVER 0.8 /* probability of crossover 杂交概率*/#define PMUTATION 0.15 /* probability of mutation 变异概率*/#define TRUE 1#define FALSE 0int generation; /* current generation no. 当前基因个数*/int cur_best; /* best individual 最优个体*/FILE *galog; /* an output 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);}/* initialize variables within the bounds *///把输入文件的变量界限输入到基因结构体中for (i = 0; i < NVARS; i++){fscanf(infile, "%lf",&lbound);fscanf(infile, "%lf",&ubound);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;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){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 = (x[1]*x[1]) - (x[1]*x[2]) + x[3];}}/***************************************************************/ /* 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 *//****************************************************************///搜寻杰出个体函数:找出最好和最坏的个体。