前言
遗传算法有很多优化和变形,本文将从最基本的遗传算法出发,以一个简单的优化问题作为例子来说明遗传算法的代码实现,比较适合已经学了相关理论知识的初学者进行实践学习。
一、问题描述
用GA求解一元函数的最大值:
f(x) = x sin(10πx) + 2.0, x∈[-1,2]
二、编码
变量x可以视为遗传算法的表现型形式,我们采用二进制编码形式。如果设定求解精度要精确到6位小数,由于区间长度为3,故将区间分为3*10^6等份,因为:
2097152 = 2^21 < 3*10^6 < 2^22 = 4194304
所以编码的二进制串长至少为22位。
我们采用二进制编码,将一个二进制串与区间[Left,Right]间对应的实数值建立对应:
假设二进制串b的十进制值为x’,则:
x = (Right-Left)*x'/(2^22-1.0)+Left;
三、产生初始种群
我们通过随机产生一些个体(即随机产生一些二进制串),来初始化我们的种群。
/*****function:generation the first popolation初始化群体*****/
void GenerateInitialPopulation (void)
{
int i,j;
srand((unsigned)(time(NULL)));
for (i=0;i
{
for (j=0;j
{
population [i].chrom[j]=(random(10)<5)?'0':'1';
}
population [i].chrom[CHROMLENGTH]='\0';
}
}
四、对种群进行评估
/****function: evaluate population according to certain formula衡量群体*****/
void EvaluatePopulation (void)
{
CalculateObjectValue ();
CalculateFitnessValue ();
FindBestAndWorstIndividual ();
}
1.计算目标函数值
/*****function: to decode a binary chromosome into a decimal integer*****/
long DecodeChromosome (char *string,int point,int length)
{
int i;
long decimal=0L;
char *pointer;
for (i=0,pointer=string+point;i
{
decimal+=(*pointer-'0')<
}
return (decimal);
}
/***** function:to calculate object value f(x) = x sin(10πx) + 2.0 *****/
void CalculateObjectValue (void)
{
int i;
long temp;
double x;
/*** rosenbrock function***/
for (i=0;i
{
temp=DecodeChromosome (population[i].chrom,0,CHROMLENGTH);
x=(Right-Left)*temp/(pow(2,CHROMLENGTH)-1.0)+Left;
population[i].value=x*sin(10*PI*x)+2.0;//函数值
population[i].x=x;//对应的自变量
}
}
2.计算适应值
在本例中,目标函数在定义域内大于0,而且求函数的最大值,所以我们直接引用目标函数作为适应度函数。
/******function: to calculate fitness value *******/
void CalculateFitnessValue (void)
{
int i;
for(i=0;i
{
population[i].fitness=population[i].value;
}
}
3.找出局部最优个体与局部最差个体,并更新全局最优个体
/*****function to find out the best individual so far current generation*****/
void FindBestAndWorstIndividual (void)
{
int i;
double sum=0.0;
/*** find out the best and worst individual of this gen