简易遗传算法(浮点数编码)

时间:2023-01-08 08:56:54

简易遗传算法(浮点数编码)简易遗传算法(浮点数编码)

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>

#define M 80//种群数量
#define XMIN -1//下限
#define XMAX 2//上限
#define PI 3.1415926
#define PC 0.8//交叉概率
#define PM 0.18//变异概率
#define PA 0.01//交叉因子

struct Node
{
double Pmember;
double Myfitness;//Myfitness是适应度
double Myfitsum;//Myfitsum是适应度占总体适应度的百分比,然后从第一个个体往后累加,主要用于选择操作
double Myfitave;
}Nownode[M],Nextnode[M];//本代群体和下一代群体

int nodeindex[M];//交叉时随机配对,存放配对的群体下标
int T=0;

double fx(double x)//根据x计算fx
{
double y;
y=x*sin(10*PI*x)+2;
//y=100-(x-5)*(x-5);
return y;
}

int calfitness()//计算适应度值
{
int i;
double minfitness,maxfitness,avefitness=0;
double C=1.7,a,b;
double temp;
minfitness=Nownode[0].Myfitness=fx(Nownode[0].Pmember);
maxfitness=minfitness;
avefitness=maxfitness;
for(i=1;i<M;i++)
{
Nownode[i].Myfitness=fx(Nownode[i].Pmember);
avefitness+=Nownode[i].Myfitness;
if(minfitness>Nownode[i].Myfitness)
{
minfitness=Nownode[i].Myfitness;
}
if(maxfitness<Nownode[i].Myfitness)
{
maxfitness=Nownode[i].Myfitness;
}
}

if(minfitness<0)//如果有负的适应度值,就把所以的适应度都加上一个数,使适应度全都为正数
{
temp=minfitness;
Nownode[0].Myfitness+=-temp;
avefitness=Nownode[0].Myfitness;
maxfitness=Nownode[0].Myfitness;
minfitness=Nownode[0].Myfitness;
for(i=1;i<M;i++)
{
Nownode[i].Myfitness+=-temp;
avefitness+=Nownode[i].Myfitness;
if(minfitness>Nownode[i].Myfitness)
{
minfitness=Nownode[i].Myfitness;
}
if(maxfitness<Nownode[i].Myfitness)
{
maxfitness=Nownode[i].Myfitness;
}
}
}

//适应度线性变换
avefitness=avefitness/M;//计算平均适应度
if(minfitness>(C*avefitness-maxfitness)/(C-1))
{
a=(C-1)*avefitness/(maxfitness-avefitness);
b=(maxfitness-C*avefitness)*avefitness/(maxfitness-avefitness);
}
else
{
a=avefitness/(avefitness-minfitness);
b=minfitness*avefitness/(avefitness-minfitness);
}
for(i=0;i<M;i++)
{
Nownode[i].Myfitness=a*Nownode[i].Myfitness+b;
}



Nownode[0].Myfitsum=Nownode[0].Myfitness;
for(i=1;i<M;i++)
{
Nownode[i].Myfitsum=Nownode[i].Myfitness+Nownode[i-1].Myfitsum;//每一个Myfitsum都是自己的适应度加上前一个的Myfitsum
}

for(i=0;i<M;i++)
{
Nownode[i].Myfitave=Nownode[M-1].Myfitsum/M;
}


for(i=0;i<M;i++)
{
Nownode[i].Myfitsum=Nownode[i].Myfitsum/Nownode[M-1].Myfitsum;//每一个Myfitsum除以所有适应度之和,使Myfitsum为0~1之间
}
return 0;
}

double randn()//产生XMIN到XMAX之间的随机数
{
return XMIN+1.0*rand()/RAND_MAX*(XMAX-XMIN);
}

int initpopulation()//初始化种群
{
int i;
for(i=0;i<M;i++)
{
Nownode[i].Pmember=randn();
}
calfitness();//计算适应度
return 0;
}

int assignment(struct Node *node1,struct Node *node2)//把node2的值赋值给node1
{
node1->Pmember=node2->Pmember;
node1->Myfitness=node2->Myfitness;
node1->Myfitsum=node2->Myfitsum;
node1->Myfitave=node2->Myfitave;
return 0;
}

int copypopulation()//复制操作
{
int i,num=0;
double temp;
while(num<M)
{
temp=1.0*rand()/RAND_MAX;
for(i=1;i<M;i++)
{
if(temp<=Nownode[0].Myfitsum)
{
assignment(&Nextnode[num++],&Nownode[0]);//把第一个个体复制到下一代
break;
}
if(temp>=Nownode[i-1].Myfitsum&&temp<=Nownode[i].Myfitsum)//把第i个个体复制到下一代
{
assignment(&Nextnode[num++],&Nownode[i]);
break;
}
}
}
for(i=0;i<M;i++)
{
assignment(&Nownode[i],&Nextnode[i]);//更新本代个体
}
calfitness();//计算适应度
return 0;
}

int isrepeat(int temp,int n)//产生随机下标判断是否重复
{
int i;
for(i=0;i<n;i++)
{
if(nodeindex[i]==temp)
return 1;
}
return 0;
}

int crossover()
{
int i,temp;
double temp_pc;
for(i=0;i<M;i++)//产生交叉点的下标
{
do {
temp=rand()%M;
} while(isrepeat(temp,i));
nodeindex[i]=temp;
}
for(i=0;i<M;i=i+2)
{
temp_pc=1.0*rand()/RAND_MAX;//如果满足交叉的条件,就开始交叉
if(temp_pc<=PC)
{
Nownode[nodeindex[i]].Pmember=PA*Nownode[nodeindex[i+1]].Pmember+(1-PA)*Nownode[nodeindex[i]].Pmember;
Nownode[nodeindex[i+1]].Pmember=PA*Nownode[nodeindex[i]].Pmember+(1-PA)*Nownode[nodeindex[i+1]].Pmember;

}
}
calfitness();//计算适应度
return 0;
}


int mutation()//变异操作
{
int i,temp;
double k=0.8,temp_pm;
for(i=0;i<M;i++)
{
temp_pm=1.0*rand()/RAND_MAX;
if(temp_pm<=PM)//如果满足变异条件,就开始变异
{
temp=rand()%2;
if(temp==0)
{
Nownode[i].Pmember=Nownode[i].Pmember+k*(XMAX-Nownode[i].Pmember)*1.0*rand()/RAND_MAX;
}
else
{
Nownode[i].Pmember=Nownode[i].Pmember-k*(Nownode[i].Pmember-XMIN)*1.0*rand()/RAND_MAX;
}
}
}
calfitness();//计算适应度
return 0;
}
int findmaxfit()//找到适应度最大的个体
{
int i,index=0;
double temp=0;
for(i=0;i<M;i++)
{
if(temp<Nownode[i].Myfitness)
{
index=i;
temp=Nownode[i].Myfitness;
}
}
return index;
}

int main()
{
int i=0,index;
int num=0,num1=0,num2=0;
srand(time(NULL));
while(num++<1000)
{
T=0;
initpopulation();
while(T++<200)
{
copypopulation();
crossover();
mutation();
}
index=findmaxfit();
if(fabs(Nownode[index].Pmember-1.85)<=0.1)
{
num1++;
}
else
{
num2++;
}
}
printf("正确的次数有%d次\n",num1);
printf("错误的次数有%d次\n",num2);
return 0;
}


简易遗传算法(浮点数编码)

简易遗传算法(浮点数编码)