码迷,mamicode.com
首页 > 编程语言 > 详细

简单遗传算法

时间:2015-06-26 11:05:31      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:c语言   编码   优化   遗传算法   struct   

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

#define M 50				//种群数量
#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.005			//变异概率

struct Node
{
	int num,MyBinary[LEN];	//num是对应二进制编码的整数值,MyBinary存放二进制编码
	double Myfitness;		//Myfitness是适应度
	double Myfitsum;		//Myfitsum是适应度占总体适应度的百分比,然后从第一个个体往后累加,主要用于选择操作
}Nownode[M],Nextnode[M];	//本代群体和下一代群体

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

double fx(double x)			//被优化函数
{
	double y;
	y=x*sin(3*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,minfitness;//minfitness作用是如果出现负的适应度,就做相应的变化
	for(i=0;i<M;i++)
	{
		temp=double2double(Nownode[i]);
		Nownode[i].Myfitness=fx(temp);
		if(i==0)
		{
			minfitness=Nownode[i].Myfitness;//i=0时,先给minfitness赋初值
		}
		if(minfitness>Nownode[i].Myfitness)
		{
			minfitness=Nownode[i].Myfitness;
		}
	}
	if(minfitness<0)//如果有负的适应度值,就把所以的适应度都加上一个数,使适应度全都为正数
	{
		for(i=0;i<M;i++)
		{
			Nownode[i].Myfitness+=-minfitness;
		}
	}
	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].Myfitsum=Nownode[i].Myfitsum/Nownode[M-1].Myfitsum;//每一个Myfitsum除以所有适应度之和,使Myfitsum为0~1之间
	}
	return 0;
}

int initpopulation()//初始化种群
{
	int i,j,temp;
	for(i=0;i<M;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<LEN;j++)
	{
		node1->MyBinary[j]=node2->MyBinary[j];
	}
	node1->num=node2->num;
	return 0;
}

int copypopulation()//选择(复制)操作
{
	int i,num=0;
	double temp;
	while(num<M)
	{
		temp=1.0*rand()/RAND_MAX;//随机生成一个0~1之间的数
		for(i=1;i<M;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<M;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<num;i++)
	{
		if(nodeindex[i]==temp)
			return 1;
	}
	return 0;
}

int bin2int(struct Node *node)//把对应的编码转化为整数值
{
	int j,num=0;;
	for(j=0;j<LEN;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<M;i++)
	{
		do
		{
			temp=rand()%M;
		} while(isrepeat(temp,i));
		
		nodeindex[i]=temp;//首先产生了交叉的下标
	}
	for(i=0;i<M;i=i+2)
	{
		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<M;i++)
	{
		for(j=0;j<LEN;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<M;i++)
	{
		if(temp<Nownode[i].Myfitness)
		{
			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<M;i++)
	{
		printf("第%d个\t%d\t%.3lf\t",i,Nownode[i].num,double2double(Nownode[i]));
		for(j=0;j<LEN;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 T=0,index,j;
	srand(time(NULL));
	initpopulation();//初始化群体
	printf("初始群体:\n");
	displaynode();
	while(T++<=50)
	{
		//printf("第%d代:\n",T);
		copypopulation();
		//printf("复制之后:\n");	
		//displaynode();
		crossover();
		//printf("交叉之后:\n");	
		//displaynode();
		mutation();	
		//printf("变异之后:\n");	
		//displaynode();
	}	
	printf("最后一代群体:\n");
	displaynode();
	index=findmaxfit();
	printf("\n\n下标\tnum值\tx值\t        编码\t\t最大适应度值\t函数最大值\n");
	printf("第%d个\t%d\t%.3lf\t",index,Nownode[index].num,double2double(Nownode[index]));
	for(j=0;j<LEN;j++)
	{
		printf("%d",Nownode[index].MyBinary[j]);
	}
	printf("\t%.3f\t\t%.3f\n\n",Nownode[index].Myfitness,fx(double2double(Nownode[index])));
	return 0;
}

技术分享

技术分享

简单遗传算法

标签:c语言   编码   优化   遗传算法   struct   

原文地址:http://blog.csdn.net/yanguilaiwuwei/article/details/46646485

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!