遗传算法二进制编码c语言,简单遗传算法(二进制编码)

#include

#include

#include

#include

#define M 80//种群数量

#define LEN 20//编码长度

#define xmin -1//下限

#define xmax 2//上限

#define MMAX (int)pow(2,LEN)//编码长度对应的最大二进制数

#define PI 3.1415926

#define PC 0.8//交叉概率

#define PM 0.05//变异概率

#define PD 0.2

struct Node

{

int num,MyBinary[LEN];//num是对应二进制编码的整数值,MyBinary存放二进制编码

double Myfitness;//Myfitness是适应度

double Myfitsum;//Myfitsum是适应度占总体适应度的百分比,然后从第一个个体往后累加,主要用于选择操作

}Nownode[M],Nextnode[M];//本代群体和下一代群体

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

int T;

double fx(double x)//被优化函数

{

double y;

y=x*sin(10*PI*x)+2;

//y=6-pow(x+6,2);

//y=sin(0.7*x)/x;

return y;

}

int randn(int temp)//产生0~MMAX之间的随机整数

{

return (int)(1.0*rand()/RAND_MAX*temp+0.5);

}

double double2double(struct Node node)//把对应的二进制数转化为对应区间的double数

{

return xmin+node.num*(xmax-xmin)/(pow(2,LEN)-1);

}

int calfitness()//计算适应度

{

int i;

double temp,temp_sum=0,minfitness,maxfitness,avefitness;//minfitness作用是如果出现负的适应度,就做相应的变化

double a,b,C=1.5;

for(i=0;i

{

temp=double2double(Nownode[i]);

Nownode[i].Myfitness=fx(temp);

temp_sum+=Nownode[i].Myfitness;

if(i==0)

{

minfitness=Nownode[i].Myfitness;//i=0时,先给minfitness赋初值

maxfitness=Nownode[i].Myfitness;

}

if(minfitness>Nownode[i].Myfitness)

{

minfitness=Nownode[i].Myfitness;

}

if(maxfitness

{

maxfitness=Nownode[i].Myfitness;

}

}

if(minfitness<0)//如果有负的适应度值,就把所以的适应度都加上一个数,使适应度全都为正数

{

temp_sum=0;

for(i=0;i

{

Nownode[i].Myfitness+=-minfitness;

temp_sum+=Nownode[i].Myfitness;

}

}

//适应度线性变换

avefitness=temp_sum/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

{

Nownode[i].Myfitness=a*Nownode[i].Myfitness+b;

}

Nownode[0].Myfitsum=Nownode[0].Myfitness;

for(i=1;i

{

Nownode[i].Myfitsum=Nownode[i].Myfitness+Nownode[i-1].Myfitsum;//每一个Myfitsum都是自己的适应度加上前一个的Myfitsum

}

for(i=0;i

{

Nownode[i].Myfitsum=Nownode[i].Myfitsum/Nownode[M-1].Myfitsum;//每一个Myfitsum除以所有适应度之和,使Myfitsum为0~1之间

}

return 0;

}

int initpopulation()//初始化种群

{

int i,j,temp;

for(i=0;i

{

temp=randn(MMAX);//产生0~MMAX之间的随机整数值

Nownode[i].num=temp;

//printf("%d\n",temp);

for(j=LEN-1;j>=0;j--)

{

Nownode[i].MyBinary[j]=temp%2;//给MyBinary赋值

temp=temp/2;

}

}

calfitness();//计算适应度

return 0;

}

int assignment(struct Node *node1,struct Node *node2)//两个个体之间赋值操作,所以这里必须使用指针,

{

int j;

for(j=0;j

{

node1->MyBinary[j]=node2->MyBinary[j];

}

node1->num=node2->num;

node1->Myfitness=node2->Myfitness;

node1->Myfitsum=node2->Myfitsum;

return 0;

}

int copypopulation()//选择(复制)操作

{

int i,num=0;

double temp;

while(num

{

temp=1.0*rand()/RAND_MAX;//随机生成一个0~1之间的数

for(i=1;i

{

if(temp>=Nownode[i-1].Myfitsum&&temp<=Nownode[i].Myfitsum)

{

//Nextnode[num++]=Nownode[i];

assignment(&Nextnode[num++],&Nownode[i]);//如果满足条件就赋值给下一代

break;

}

}

}

for(i=0;i

{

//Nownode[i]=Nextnode[i];

assignment(&Nownode[i],&Nextnode[i]);//更新本代个体

}

calfitness();//计算适应度

return 0;

}

int isrepeat(int temp,int num)//交叉时要随机分组,防止出现重复的两个数,此函数检测是否下标重复

{

int i;

for(i=0;i

{

if(nodeindex[i]==temp)

return 1;

}

return 0;

}

int bin2int(struct Node *node)//把对应的编码转化为整数值

{

int j,num=0;;

for(j=0;j

{

num+=(int)(pow(2,LEN-1-j)*(node->MyBinary[j]));

}

node->num=num;

return num;

}

int crossposition(struct Node *node1,struct Node *node2,int p)//交叉操作,交叉点为p,参数必须是指针

{

int j,temp;

for(j=LEN-1;j>=LEN-1-p;j--)

{

temp=node1->MyBinary[j];

node1->MyBinary[j]=node2->MyBinary[j];//交换两个个体的编码

node2->MyBinary[j]=temp;

}

bin2int(node1);//交叉完成后更新num值

bin2int(node2);

return 1;

}

int crossover()

{

int i,temp;

double pc_temp;

for(i=0;i

{

do

{

temp=rand()%M;

} while(isrepeat(temp,i));

nodeindex[i]=temp;//首先产生了交叉的下标

}

for(i=0;i

{

temp=rand()%(LEN-1);

pc_temp=1.0*rand()/RAND_MAX;

if(pc_temp<=PC)//满足交叉条件就交叉

{

crossposition(&Nownode[nodeindex[i]],&Nownode[nodeindex[i+1]],temp);

}

}

calfitness();//计算适应度

return 1;

}

int mutation()//变异操作

{

int i,j;

double pm_temp;

for(i=0;i

{

for(j=0;j

{

pm_temp=1.0*rand()/RAND_MAX;

if(pm_temp<=PM)//满足变异概率就进行变异操作

{

Nownode[i].MyBinary[j]=(Nownode[i].MyBinary[j]==0)?1:0;

}

}

bin2int(&Nownode[i]);//更新个体的num值

}

calfitness();//计算适应度

return 1;

}

int findmaxfit()//找到适应度最大的个体

{

int i,index=0;

double temp=0;

for(i=0;i

{

if(temp

{

index=i;

temp=Nownode[i].Myfitness;

}

}

return index;

}

int displaynode()

{

int i,j;

printf("\n\n下标\tnum值\tx值\t 编码\t\tMyfitness\tMyfitsum\n");

for(i=0;i

{

printf("第%d个\t%d\t%.3lf\t",i,Nownode[i].num,double2double(Nownode[i]));

for(j=0;j

{

printf("%d",Nownode[i].MyBinary[j]);

}

printf("\t%.3lf\t\t%.3lf\n",Nownode[i].Myfitness,Nownode[i].Myfitsum);

}

return 1;

}

int main()

{

int index;

int num=0,num1=0,num2=0;

srand(time(NULL));

while(num++<100)

{

T=0;

initpopulation();//初始化群体

while(T++<=100)

{

copypopulation();

crossover();

mutation();

}

index=findmaxfit();

if(fabs(double2double(Nownode[index])-1.8)<=0.1)

{

num1++;

}

else

{

num2++;

}

}

printf("正确的结果次数有%d次\n",num1);

printf("错误的结果次数有%d次\n",num2);

return 0;

}

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

根据结果可知,计算结果正确的概率在98%以上。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值