最新消息: USBMI致力于为网友们分享Windows、安卓、IOS等主流手机系统相关的资讯以及评测、同时提供相关教程、应用、软件下载等服务。

遗传算法

IT圈 admin 23浏览 0评论

遗传算法

问题:求f(x)=x+10*sin(5x)+7*cos(4x)最大值, 0<=x<=9

新建输入文件gadata.txt,内容为:
0, 9
表示变量x的下界和上界。
新建日志文件galog.txt,用于记录计算过程及输出结果。

// 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变异替换均匀变异,可能得到更好的效果。  
代码没有任何图形,甚至也没有屏幕输出,主要是保证在平台之间的高可移植性。 读者可以从ftp.uncc.edu, 目录 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 = 1; /* no. of problem variables 问题变量的个数*/  
#define PXOVER 0.8 /* probability of crossover 杂交概率*/  
#define PMUTATION 0.15 /* probability of mutation 变异概率*/  
#define TRUE 1 
#define FALSE 0    
#define PI 3.1415926int 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] + 10 * sin(5 * x[1]) + 7 * cos(4 * x[1]) */   
/*************************************************************/  
//评价函数,可以由用户自定义,该函数取得每个基因的适应度    
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] + 10 * sin(5 * x[1]) + 7 * cos(4 * x[1]);    }  
}  /***************************************************************/  
/* 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 */   
/**************************************************************/   
//选择函数:用于最大化合并杰出模型的标准比例选择,保证最优秀的个体得以生存 
void select(void)  
{   int mem, j, i;   double sum = 0;   double p;      /* find total fitness of the population */   //找出种群的适应度之和   for (mem = 0; mem < POPSIZE; mem++)   {    sum += population[mem].fitness;   }     /* calculate relative fitness */   //计算相对适应度    for (mem = 0; mem < POPSIZE; mem++)  {     population[mem].rfitness = population[mem].fitness/sum;   }   population[0].cfitness = population[0].rfitness;      /* calculate cumulative fitness */   //计算累加适应度   for (mem = 1; mem < POPSIZE; mem++)   {    population[mem].cfitness = population[mem-1].cfitness + population[mem].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];   
} /***************************************************************/  
/* Crossover selection: selects two parents that take part in */  
/* the crossover. Implements a single point crossover */   
/***************************************************************/  
//杂交函数:选择两个个体来杂交,这里用单点杂交 
void crossover(void)  
{   int mem, one;    int first = 0; /* count of the number of members chosen */    double x;  for (mem = 0; mem < POPSIZE; ++mem)   {    x = rand()%1000/1000.0;    if (x < PXOVER)    {     ++first;     if (first % 2 == 0)      Xover(one, mem);     else       one = mem;       }    }   
}   /**************************************************************/  
/* Crossover: performs crossover of the two selected parents. */  
/**************************************************************/ 
//交叉   
void Xover(int one, int two)  
{   int i;   int point; /* crossover point */     /* select crossover point */   if(NVARS > 1)   {    if(NVARS == 2)     point = 1;    else     point = (rand() % (NVARS - 1)) + 1;        for (i = 0; i < point; i++)     swap(&population[one].gene[i], &population[two].gene[i]);          }  
}    /*************************************************************/  
/* Swap: A swap procedure that helps in swapping 2 variables */   
/*************************************************************/    
void swap(double *x, double *y)  
{   double temp;  temp = *x;   *x = *y;   *y = temp;     
}    /**************************************************************/  
/* Mutation: Random uniform mutation. A variable selected for */  
/* mutation is replaced by a random value between lower and */  
/* upper bounds of this variable */   
/**************************************************************/  
//变异函数:被该函数选中后会使得某一变量被一个随机的值所取代 
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)     {      /* find the bounds on the variable to be mutated 确定*/       lbound = population[i].lower[j];       hbound = population[i].upper[j];      population[i].gene[j] = randval(lbound, hbound);       }     }   
}     /***************************************************************/  
/* Report function: Reports progress of the simulation. Data */  
/* dumped into the output file are separated by commas */   
/***************************************************************/    
//报告模拟进展情况。输出文件中的数据用逗号隔开
void report(void)  
{   int i;   double best_val;   /* best population fitness 最佳种群适应度*/   double avg;        /* avg population fitness 平均种群适应度*/    double stddev;     /* std. deviation of population fitness 种群适应度偏差 */  double sum_square;  /* sum of square for std. calc 各个个体平方之和*/   double square_sum;  /* square of sum for std. calc 平均值的平方乘个数*/   double sum;        /* total population fitness 所有种群适应度之和*/      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 * POPSIZE;    stddev = sqrt((sum_square - square_sum)/(POPSIZE - 1));   best_val = population[POPSIZE].fitness;       fprintf(galog, "\n generation=%5d, best_val=%6.3f, avg=%6.3f, stddev=%6.3f \n\n", generation,  best_val, avg, stddev);  
}     /**************************************************************/  
/* 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;      if ((galog = fopen("galog.txt","w"))==NULL)   {    exit(1);   }    generation = 0;      fprintf(galog, "\n generation best average standard \n");   fprintf(galog, " number value fitness deviation \n");      initialize();   evaluate();    //评价函数,可以由用户自定义,该函数取得每个基因的适应度keep_the_best();    //保存每次遗传后的最佳基因while(generation<MAXGENS)   {    generation++;    select();     //选择函数:用于最大化合并杰出模型的标准比例选择,保证最优秀的个体得以生存crossover();  //杂交函数:选择两个个体来杂交,这里用单点杂交 mutate();     //变异函数:被该函数选中后会使得某一变量被一个随机的值所取代 report();     //报告模拟进展情况evaluate();   //评价函数,可以由用户自定义,该函数取得每个基因的适应度elitist();    //搜寻杰出个体函数:找出最好和最坏的个体。如果某代的最好个体比前一代的最好个体要坏,那么后者将会取代当前种群的最坏个体 }    fprintf(galog,"\n\n Simulation completed\n");   fprintf(galog,"\n Best member: \n");      for (i = 0; i < NVARS; i++)   {     fprintf (galog,"\n var(%d) = %3.3f",i,population[POPSIZE].gene[i]);   }    fprintf(galog,"\n\n Best fitness = %3.3f",population[POPSIZE].fitness);   fclose(galog);     printf("Success\n");   
}   
/***************************************************************/ 

计算结果为:
x=7.857 f(x)=24.855

注:遗传算法用来取得近似最优解,而不是最优解

遗传算法

问题:求f(x)=x+10*sin(5x)+7*cos(4x)最大值, 0<=x<=9

新建输入文件gadata.txt,内容为:
0, 9
表示变量x的下界和上界。
新建日志文件galog.txt,用于记录计算过程及输出结果。

// 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变异替换均匀变异,可能得到更好的效果。  
代码没有任何图形,甚至也没有屏幕输出,主要是保证在平台之间的高可移植性。 读者可以从ftp.uncc.edu, 目录 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 = 1; /* no. of problem variables 问题变量的个数*/  
#define PXOVER 0.8 /* probability of crossover 杂交概率*/  
#define PMUTATION 0.15 /* probability of mutation 变异概率*/  
#define TRUE 1 
#define FALSE 0    
#define PI 3.1415926int 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] + 10 * sin(5 * x[1]) + 7 * cos(4 * x[1]) */   
/*************************************************************/  
//评价函数,可以由用户自定义,该函数取得每个基因的适应度    
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] + 10 * sin(5 * x[1]) + 7 * cos(4 * x[1]);    }  
}  /***************************************************************/  
/* 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 */   
/**************************************************************/   
//选择函数:用于最大化合并杰出模型的标准比例选择,保证最优秀的个体得以生存 
void select(void)  
{   int mem, j, i;   double sum = 0;   double p;      /* find total fitness of the population */   //找出种群的适应度之和   for (mem = 0; mem < POPSIZE; mem++)   {    sum += population[mem].fitness;   }     /* calculate relative fitness */   //计算相对适应度    for (mem = 0; mem < POPSIZE; mem++)  {     population[mem].rfitness = population[mem].fitness/sum;   }   population[0].cfitness = population[0].rfitness;      /* calculate cumulative fitness */   //计算累加适应度   for (mem = 1; mem < POPSIZE; mem++)   {    population[mem].cfitness = population[mem-1].cfitness + population[mem].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];   
} /***************************************************************/  
/* Crossover selection: selects two parents that take part in */  
/* the crossover. Implements a single point crossover */   
/***************************************************************/  
//杂交函数:选择两个个体来杂交,这里用单点杂交 
void crossover(void)  
{   int mem, one;    int first = 0; /* count of the number of members chosen */    double x;  for (mem = 0; mem < POPSIZE; ++mem)   {    x = rand()%1000/1000.0;    if (x < PXOVER)    {     ++first;     if (first % 2 == 0)      Xover(one, mem);     else       one = mem;       }    }   
}   /**************************************************************/  
/* Crossover: performs crossover of the two selected parents. */  
/**************************************************************/ 
//交叉   
void Xover(int one, int two)  
{   int i;   int point; /* crossover point */     /* select crossover point */   if(NVARS > 1)   {    if(NVARS == 2)     point = 1;    else     point = (rand() % (NVARS - 1)) + 1;        for (i = 0; i < point; i++)     swap(&population[one].gene[i], &population[two].gene[i]);          }  
}    /*************************************************************/  
/* Swap: A swap procedure that helps in swapping 2 variables */   
/*************************************************************/    
void swap(double *x, double *y)  
{   double temp;  temp = *x;   *x = *y;   *y = temp;     
}    /**************************************************************/  
/* Mutation: Random uniform mutation. A variable selected for */  
/* mutation is replaced by a random value between lower and */  
/* upper bounds of this variable */   
/**************************************************************/  
//变异函数:被该函数选中后会使得某一变量被一个随机的值所取代 
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)     {      /* find the bounds on the variable to be mutated 确定*/       lbound = population[i].lower[j];       hbound = population[i].upper[j];      population[i].gene[j] = randval(lbound, hbound);       }     }   
}     /***************************************************************/  
/* Report function: Reports progress of the simulation. Data */  
/* dumped into the output file are separated by commas */   
/***************************************************************/    
//报告模拟进展情况。输出文件中的数据用逗号隔开
void report(void)  
{   int i;   double best_val;   /* best population fitness 最佳种群适应度*/   double avg;        /* avg population fitness 平均种群适应度*/    double stddev;     /* std. deviation of population fitness 种群适应度偏差 */  double sum_square;  /* sum of square for std. calc 各个个体平方之和*/   double square_sum;  /* square of sum for std. calc 平均值的平方乘个数*/   double sum;        /* total population fitness 所有种群适应度之和*/      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 * POPSIZE;    stddev = sqrt((sum_square - square_sum)/(POPSIZE - 1));   best_val = population[POPSIZE].fitness;       fprintf(galog, "\n generation=%5d, best_val=%6.3f, avg=%6.3f, stddev=%6.3f \n\n", generation,  best_val, avg, stddev);  
}     /**************************************************************/  
/* 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;      if ((galog = fopen("galog.txt","w"))==NULL)   {    exit(1);   }    generation = 0;      fprintf(galog, "\n generation best average standard \n");   fprintf(galog, " number value fitness deviation \n");      initialize();   evaluate();    //评价函数,可以由用户自定义,该函数取得每个基因的适应度keep_the_best();    //保存每次遗传后的最佳基因while(generation<MAXGENS)   {    generation++;    select();     //选择函数:用于最大化合并杰出模型的标准比例选择,保证最优秀的个体得以生存crossover();  //杂交函数:选择两个个体来杂交,这里用单点杂交 mutate();     //变异函数:被该函数选中后会使得某一变量被一个随机的值所取代 report();     //报告模拟进展情况evaluate();   //评价函数,可以由用户自定义,该函数取得每个基因的适应度elitist();    //搜寻杰出个体函数:找出最好和最坏的个体。如果某代的最好个体比前一代的最好个体要坏,那么后者将会取代当前种群的最坏个体 }    fprintf(galog,"\n\n Simulation completed\n");   fprintf(galog,"\n Best member: \n");      for (i = 0; i < NVARS; i++)   {     fprintf (galog,"\n var(%d) = %3.3f",i,population[POPSIZE].gene[i]);   }    fprintf(galog,"\n\n Best fitness = %3.3f",population[POPSIZE].fitness);   fclose(galog);     printf("Success\n");   
}   
/***************************************************************/ 

计算结果为:
x=7.857 f(x)=24.855

注:遗传算法用来取得近似最优解,而不是最优解

发布评论

评论列表 (0)

  1. 暂无评论