简单遗传算法

#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;
}

时间: 2024-08-24 18:50:42

简单遗传算法的相关文章

简单遗传算法-python实现

ObjFunction.py 1 import math 2 3 4 def GrieFunc(vardim, x, bound): 5 """ 6 Griewangk function 7 """ 8 s1 = 0. 9 s2 = 1. 10 for i in range(1, vardim + 1): 11 s1 = s1 + x[i - 1] ** 2 12 s2 = s2 * math.cos(x[i - 1] / math.sqrt(i

进化策略-python实现

ESIndividual.py 1 import numpy as np 2 import ObjFunction 3 4 5 class ESIndividual: 6 7 ''' 8 individual of evolutionary strategy 9 ''' 10 11 def __init__(self, vardim, bound): 12 ''' 13 vardim: dimension of variables 14 bound: boundaries of variable

克隆选择算法-python实现

CSAIndividual.py 1 import numpy as np 2 import ObjFunction 3 4 5 class CSAIndividual: 6 7 ''' 8 individual of clone selection algorithm 9 ''' 10 11 def __init__(self, vardim, bound): 12 ''' 13 vardim: dimension of variables 14 bound: boundaries of va

差分进化算法-python实现

DEIndividual.py 1 import numpy as np 2 import ObjFunction 3 4 5 class DEIndividual: 6 7 ''' 8 individual of differential evolution algorithm 9 ''' 10 11 def __init__(self, vardim, bound): 12 ''' 13 vardim: dimension of variables 14 bound: boundaries

和声搜索算法-python实现

HSIndividual.py 1 import numpy as np 2 import ObjFunction 3 4 5 class HSIndividual: 6 7 ''' 8 individual of harmony search algorithm 9 ''' 10 11 def __init__(self, vardim, bound): 12 ''' 13 vardim: dimension of variables 14 bound: boundaries of varia

人工鱼群算法-python实现

AFSIndividual.py 1 import numpy as np 2 import ObjFunction 3 import copy 4 5 6 class AFSIndividual: 7 8 """class for AFSIndividual""" 9 10 def __init__(self, vardim, bound): 11 ''' 12 vardim: dimension of variables 13 bound:

粒子群优化算法-python实现

PSOIndividual.py 1 import numpy as np 2 import ObjFunction 3 import copy 4 5 6 class PSOIndividual: 7 8 ''' 9 individual of PSO 10 ''' 11 12 def __init__(self, vardim, bound): 13 ''' 14 vardim: dimension of variables 15 bound: boundaries of variables

游戏开发中的人工智能 复习

游戏开发中的人工智能 复习 (个人复习,一些仅是给自己的复习提示(=w=),转载注明出处:http://blog.csdn.net/hcbbt/article/details/42815479) 配套教材:游戏开发中的人工智能 知识点 移动 Bresenham,视线(略),拦截 // Bresenham if (deltaCol > deltaRow) { fraction = deltaRow * 2 - deltaCol; while (nextCol != endCol) { if (fr

这份研究花了我一年:数据挖掘与运维分析

这份研究报告,作者从去年开始到现在花了整整一年时间,今天和大家分享下,关于<数据采矿和运维分析>,共同探讨~ 数据挖掘(Data Mining)是从大量数据中提取或"挖掘"知识. 广义数据挖掘:数据挖掘是从存放在数据库.数据仓库或其它信息库中的大量数据挖掘有趣知识的过程. 数据挖掘技术侧重:1)概率与数理统计 2)数据库技术 3)人工智能技术 4)机器学习. 1. 数据清理:消除噪音或不一致数据 2. 数据集成:多种数据源可以组合在一起 3. 数据选择:从数据库中提取与分析