///Users/apple/Documents/ga/ga.xcodeproj
// main.c
// ga
//
// Created by APPLE on 16/3/31.
// Copyright © 2016年 ETaoBook. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define POPSIZE 500
#define MAXIMIZATION 1
#define MINIMIZATION 2
#define Cmax 100
#define Cmin 0
//x1
#define LENGTH1 10
//x2
#define LENGTH2 10
//一个染色体
#define CHROMLENGTH LENGTH1+LENGTH2
//功能模式
int FunctionMode=MAXIMIZATION;
//群体大小
int PopSize=80;
//终止代数
int MaxGeneration=1000;
//交叉概率
double Pc=0.6;
//变异概率
double pm=0.001;
//个体
struct individual{
double value;
double fitness;//适应度
char chrom[CHROMLENGTH];
};
int generation;
int best_index;
int worst_index;
struct individual bestindividual;
struct individual worstindividual;
struct individual currentbest;
struct individual population[POPSIZE];
void GenerateInitialPopulation(void);//生成初代群体
void GenerateNextPopulation(void);//生成下代群体
void EvaluatePopulation(void);//对个体进行评价
long DecodeChromosome(char *,int,int);//解码
void CalculateObjectValue(void);//计算函数值
void CalculateFitnessValue(void);//计算适应度
void FindBestAndWorstIndividual(void);//找到最好的个体在当前这一代
void PerformEvolution(void);
void SelectionOperator(void);//选择运算
void CrossoverOperator(void);//交叉运算
void MutationOperator(void);//变异运算
void OutputTextReport(void);
int main(void) {
generation =0;
GenerateInitialPopulation();
EvaluatePopulation();
while (generation<MaxGeneration) {
generation++;
GenerateNextPopulation();
EvaluatePopulation();
PerformEvolution();
OutputTextReport();
}
return 0;
}
void GenerateInitialPopulation(void){
int i,j;
srand((unsigned)time(NULL));//初始化随机数生成器
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(void){
SelectionOperator();
CrossoverOperator();
MutationOperator();
}
void EvaluatePopulation(void){
CalculateObjectValue();//计算函数值
CalculateFitnessValue();//计算适应度
FindBestAndWorstIndividual();//找出最佳个体
}
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;
}
void CalculateObjectValue(void){//计算函数值
int i;
long temp1,temp2;
double x1,x2;
for (i=0; i<PopSize; i++) {
temp1=DecodeChromosome(population[i].chrom,0 , LENGTH1);
temp2=DecodeChromosome(population[i].chrom, LENGTH1, LENGTH2);
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);
}
}
void CalculateFitnessValue(void){//计算适应度
int i;
double temp = 0.0;
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(void){
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) {
currentbest=bestindividual;
}else{
if (bestindividual.fitness<currentbest.fitness) {
currentbest=bestindividual;
}
}
}
void PerformEvolution(void){
if (bestindividual.fitness<currentbest.fitness) {
currentbest=population[best_index];
}else{
population[worst_index]=currentbest;
}
}
void SelectionOperator(void){//选择运算
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;
}
for (i=1; i<PopSize; i++) {
cfitness[i]=cfitness[i-1]+cfitness[i];
}
for (i=0; i<PopSize; i++) {
p=rand()%1000/1000.0;
index=0;
while (p>cfitness[index]) {
index++;
}
newpopulation[i]=population[index];
}
for (i=0; i<PopSize; i++) {
population[i]=newpopulation[i];
}
}
void CrossoverOperator(void){//交叉算子
int i,j;
int index[POPSIZE];
int point,temp;
double p;
char ch;
for (i=0; i<PopSize; i++) {
index[i]=i;
}
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=(rand()%CHROMLENGTH-i)+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(void){//变异
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(void){
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);
for (i=0; i<CHROMLENGTH; i++) {
printf("%c",currentbest.chrom[i]);
}
printf("\n");
}