generic.cpp:
generic.h:
/////////////////////////////////////////////////////////////////////
///
/// SIMPLE GENERIC ALGORITHM
///
/////////////////////////////////////////////////////////////////////
#include "generic.h"
int const FunctionMode = MAXIMIZATION;
int const PopSize = 80;
int const MaxGeneration = 200; //最大代数
double Pc = 0.7; //交叉的概率
double Pm = 0.05; //突变的概率
int generation;
int best_index;
int worst_index;
struct individual bestindividual;
struct individual worstindividual;
struct individual currentbest;
struct individual population[PopSize];
int g;
////////////////////////////////////////////////
//
// 遗传算法
//
int generic()
{
srand(time(0));
generation = 0;
GenerateInitialPopulation();
EvaluatePopulation();
while (generation < MaxGeneration)
{
generation++;
GenerateNextPopulation();
EvaluatePopulation();
PerformEvolution();
// OutputTextReport();
}
// printf("gen:%d, %d\n", );
return 0;
}
// 初始化函数,对种群中每个个体中的每个基因,都用rand函数来随机初始化。
void GenerateInitialPopulation()
{
int i, j;
for (i=0; i<PopSize; i++)
{
for (j=0; j<CHROMLENGTH; j++)
{
population[i].chrom[j] = ((rand()%10)<5)?'0':'1';
}
population[i].chrom[CHROMLENGTH]='\0';
}
}
//生成下一代
void GenerateNextPopulation()
{
SelectionOperator();
CrossoverOperator();
MutationOperator();
}
void EvaluatePopulation()
{
CalculateObjectValue();
CalculateFitnessValue();
FindBestAndWorstIndividual();
}
//解码:二进制转化为长整型long
long DecodeChromosome(char *string, int point, int length)
{
int i;
long decimal = 0L;
char *pointer;
for (i=0,pointer=string+point; i<length; i++,pointer++)
{
decimal += (*pointer - '0')<<(length - 1 - i);
}
return (decimal);
}
//
// f(x1, x2) = 100 * (x2^2-x2)^2 + (1-x1)^2;
// max: f(-2.048, -2.048) = 3905.926227
// 由population[i].chrom中的二进制值,解码,函数运算后,
// 将结果存到population[i].value中去
void CalculateObjectValue()
{
int i;
long temp1, temp2;
double x1, x2;
for (i=0; i<PopSize; i++)
{
// 由二进制序列转化为long型的 x1, x2
temp1 = DecodeChromosome(population[i].chrom, 0, LENGTH1);
temp2 = DecodeChromosome(population[i].chrom, LENGTH1, LENGTH2);
// 抽样值还原为原定义域内的值,
// 原定义域:- 2.048:2.048, 区间长度4.096
x1 = 4.096 * temp1 / 1023.0 - 2.048;
x2 = 4.096 * temp2 / 1023.0 - 2.048;
population[i].value = 100 * (x1*x1 - x2) * (x1*x1 - x2) + (1 - x1)*(1 - x1);
}
}
//
// 适应度计算,由population[i].value算出适应度population[i].fitness
// 需要 知道,是求最大值还是求最小值:MAXIMIZATION,MINIMIZATION
//
void CalculateFitnessValue()
{
int i;
double temp;
for (i=0; i<PopSize; i++)
{
if (FunctionMode == MAXIMIZATION)
{
if ((population[i].value + Cmin) > 0.0)
{
temp = Cmin + population[i].value;
}
else
{
temp = 0.0;
}
}
else if (FunctionMode == MINIMIZATION)
{
if (population[i].value < Cmax)
{
temp = Cmax - population[i].value;
}
else
{
temp = 0.0;
}
}
population[i].fitness = temp;
}
}
// 已经算好了适应度,计算出最佳的和最差的,以及当前最佳的
//
void FindBestAndWorstIndividual()
{
int i;
double sum = 0.0;
bestindividual = population[0];
worstindividual = population[0];
for (i=1; i<PopSize; i++)
{
if (population[i].fitness > bestindividual.fitness)
{
bestindividual = population[i];
best_index = i;
}
else if (population[i].fitness < worstindividual.fitness)
{
worstindividual = population[i];
worst_index = i;
}
sum += population[i].fitness;
}
if (generation == 0)
{
g = 0;
currentbest = bestindividual;
}
else if (bestindividual.fitness > currentbest.fitness)
{
currentbest = bestindividual;
g = generation;
}
}
// 进化,用“史上最好”代替"当前最差"
void PerformEvolution()
{
if (bestindividual.fitness > currentbest.fitness)
{
currentbest = population[best_index];
}
else
{
population[worst_index] = currentbest;
}
}
// 选择算法
void SelectionOperator()
{
int i, index;
double p, sum = 0.0;
double cfitness[PopSize]; // 归一化适应度,也就是概率
struct individual newpopulation[PopSize];
// 算出总的适应度
for (i=0; i<PopSize; i++)
{
sum += population[i].fitness;
}
// 算出归一化适应度
for (i=0; i<PopSize; i++)
{
cfitness[i] = population[i].fitness / sum;
}
// 算出归一化适应度的前n项和
for (i=1; i<PopSize; i++)
{
cfitness[i] = cfitness[i - 1] + cfitness[i];
}
for (i=0; i<PopSize; i++)
{
p = rand()%1000/1000.0; // 0-1 之间,3位小数
index = 0;
while (p > cfitness[index])
{
index++;
}
newpopulation[i] = population[index];
}
// 赋值,新一代正式生成
for (i=0; i<PopSize; i++)
{
population[i] = newpopulation[i];
}
}
// 交叉互换
void CrossoverOperator()
{
int i, j;
int index[PopSize];
int point, temp;
double p;
char ch;
for (i=0; i<PopSize; i++)
{
index[i] = i;
}
// index数列中的每一个元素,都随机指定数列中在它之后的另一元素,
// 然后两者互换,目的是打乱数组,实现两两配对的随机
for (i=0; i<PopSize; i++)
{
point = rand()%(PopSize - i);
temp = index[i];
index[i] = index[point + i];
index[point + i] = temp;
}
for (i=0; i<PopSize - 1; i+=2)
{
p=rand()%1000/1000.0;
if (p<Pc)
{
// point从1到20;意味着从point到最后一个,这么一段要互换
point = rand()%(CHROMLENGTH - 1) + 1;
for (j=point; j<CHROMLENGTH; j++)
{
ch = population[index[i]].chrom[j];
population[index[i]].chrom[j] = population[index[i+1]].chrom[j];
population[index[i+1]].chrom[j] = ch;
}
}
}
}
// 突变
void MutationOperator()
{
int i, j;
double p;
for (i=0; i<PopSize; i++)
{
for (j=0; j<CHROMLENGTH; j++)
{
p = rand()%1000/1000.0;
if (p<Pm)
{
population[i].chrom[j] = (population[i].chrom[j] == '0')?'1':'0';
}
}
}
}
// 输出结果
void OutputTextReport()
{
int i;
double sum;
double average;
sum = 0.0;
for (i=0; i<PopSize; i++)
{
sum += population[i].value;
}
average = sum/PopSize;
printf("gen=%d, avg=%f, best=%f,", generation, average, currentbest.value);
printf("chromosome=");
for (i=0; i<CHROMLENGTH; i++)
{
printf("%c", currentbest.chrom[i]);
}
printf("\n");
}
generic.h:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
//常量
#define POSIZE 500 //M,群体规模
#define MAXIMIZATION 1 //maximization falg
#define MINIMIZATION 2 //minimization flag
//
#define Cmax 100 //最大值
#define Cmin 0 //最小值
#define LENGTH1 10 //第一个自变量采量化编码后的二进制长度
#define LENGTH2 10 //第二个自变量采量化编码后的二进制长度
#define CHROMLENGTH (LENGTH1+LENGTH2) //总长度
// 个体
struct individual
{
char chrom[CHROMLENGTH + 1];
double value;
double fitness;
};
int generic();
void GenerateInitialPopulation();
void GenerateNextPopulation();
//GenerateNextPopulation
void SelectionOperator();
void CrossoverOperator();
void MutationOperator();
void EvaluatePopulation();
//EvaluatePopulation
void CalculateObjectValue();
void CalculateFitnessValue();
void FindBestAndWorstIndividual();
long DecodeChromosome(char *string, int point, int length);
void PerformEvolution();
void OutputTextReport();
main.cpp:
#include "generic.h"
int gg[1000];
double cc[1000];
extern struct individual currentbest;
extern int g;
///////////////////////////////////
///主函数
int main()
{
int i;
double sum = 0;
double f = 0.0;
for (i=0; i<1000; i++)
{
gg[i] = g;
generic();
cc[i] = currentbest.value;
printf("best:%f,index:%d\n", cc[i], gg[i]);
Sleep(1500);
}
for (i=0; i<1000; i++)
{
if (cc[i] > 3905)
{
f += 0.001;
}
sum += gg[i];
}
sum /= 1000;
printf("rate:%f,index:%f\n", f, sum);
return 0;
}