主函数:
int main()
{
srand((unsigned)time(NULL));
init();
GA();
system(“pause”);
return 0;
}
init函数:
void init() //初始化 建立一个种群
{
inttmp;
for(int i=0;i<SIZE;i++)
{
tmp=randi(N);
for(int j=0;j<LEN;j++)
{
cur[i].x[j]=tmp%2; //存储在一定范围内产生随机数被2取余的余数
tmp=tmp>>1;
}
}
cal_fitness();
}
randi函数:
int randi(int k)
{
return (int)(randd()*k+0.5); //randi()函数生成均匀分布的伪随机整数,范围为imin–imax,如果没指定imin,则默认为1。r =randi(imax,n):生成n*n的矩阵
}
randd函数:
double randd()
{
return (double)rand()/RAND_MAX; // rand()函数是产生随机数的一个随机函数
}
//计算当前种群中各个个体的适应度
void cal_fitness()
{
inti,j,k;
double d;
for(i=0;i<SIZE;i++)
{
k=0;
for(j=LEN-1;j>=0;j–) k=(k<<1)+cur[i].x[j]; //累加在一定范围内的余数
d=(double)k/N*3-1; //d即为在该范围内的一个数值
cur[i].fitness=d*sin(10*PI*d)+2; //fitness代表该数所求的函数值
cur[i].fitsum=i>0?(cur[i].fitness+cur[i-1].fitsum):(cur[0].fitness); //除第0个数之外求该数d所对应的函数值的和前一个的和
}
}
//遗传进化函数
void GA()
{
intcnt=0;
double ans;
while(cnt++<MAXGEN)
{
tran(); //进行换代操作
// printf(“%.6lf\n”,max.fitness);
// printcur();
}
ans=cur[0].fitness;
for(int i=1;i<SIZE;i++) ans=MAX(ans,cur[i].fitness); // 找到适应度最大的值即为该函数的值
printf(“%.6lf\n”,ans);
}
tran函数:
//换代
void tran()
{
inti,j,pos;
//找当前种群最优个体
max=cur[0];
for(i=1;i<SIZE-1;i++)
{
if(cur[i].fitness>max.fitness) max=cur[i];
}
for(int k=0;k<SIZE;k+=2)
{
//选择交叉个体
i=sel();
j=sel();
//选择交叉位置
pos=randi(LEN-1);
//交叉
if(randd()<P_CORSS) //如果小于交叉概率则进行 如果大于 则进行else
{
memcpy(next[k].x,cur[i].x,pos); //直接把cur【i】.x 拷贝到 next【i】.x
memcpy(next[k].x+pos,cur[j].x+pos,LEN-pos); //第pos位置进行复制 从j中第pos起 总共LEN-pos 复制上去 相当于交叉
memcpy(next[k+1].x,cur[j].x,pos);
memcpy(next[k+1].x+pos,cur[i].x+pos,LEN-pos); 同理 xj分别产生 一个交叉
}
else
{
memcpy(next[k].x,cur[i].x,LEN); //直接把复制到下一代 基因型不改变
memcpy(next[k+1].x,cur[j].x,LEN);
}
//变异
if(randd()<P_MUTATION) //如果小于则进行变异操作
{
pos=randi(LEN-1); //产生随机数 确定变异的位置在len-1的范围内
next[k].x[pos]^=next[k].x[pos];
pos=randi(LEN-1); //再次进行
next[k+1].x[pos]^=next[k+1].x[pos]; //在pos位置变为原来的平方
}
}
//找下一代的最差个体
min=next[0],j=0;
for(i=1;i<SIZE-1;i++)
{
if(next[i].fitness<min.fitness) min=next[i],j=i; //下一代中适应度最低的值
}
//用上一代的最优个体替换下一代的最差个体
next[j]=max;
memcpy(cur,next,sizeof(cur));
cal_fitness(); //再次求新一代适应度
}
sel函数:
int sel()
{
double p=randd(); //产生一个随机数
double sum=cur[SIZE-1].fitsum; //找到结尾数的最好的适应度
for(int i=0;i<SIZE;i++)
{
if(cur[i].fitsum/sum>p) return i; //然后从头到尾找到适应度 大于产生的随机数如果有则返回i
}
}
memcpy函数: //拷贝函数 调用string 函数即可
//打印个体适应度和二进制编码
void print(node tmp)
{
printf(“%.6lf”,tmp.fitness);
for(int i=0;i<LEN;i++) printf(” %d”,tmp.x[i]);
printf(“\n”);
}
//打印种群
void printcur()
{
for(int i=0;i<SIZE;i++) print(cur[i]);
}
/*
用遗传算法求y=x*sin(10*pi*x)+2的最大值 -1=<x<=2
精确到6位小数
pow(2,21)<3*1000000<pow(2,22)
编码的二进制长度为22
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctime>
#include <math.h>
#define N 3000000
#define PI 3.14159265
#define MAX(a,b) ((a)>(b)?(a):(b))
#define SIZE 50
#define MAXGEN 50
#define P_CORSS 0.75
#define P_MUTATION 0.05
#define LEN 22
typedef struct node
{
char x[LEN]; //存储编码
double fitness,fitsum; //第一个为最适合 第二个适应度和
}node; //构建一个结构体来存储
node cur[SIZE],next[SIZE],max,min;