(完整版)遗传算法c语言代码
- 格式:doc
- 大小:49.51 KB
- 文档页数:6
遗传算法是一种模拟自然选择过程的优化算法,可以用于解决各种复杂的组合优化问题。
其中,旅行商问题是一个经典的组合优化问题,也是一个典型的NP难题,即寻找最优解的时间复杂度是指数级的。
在本文中,我们将讨论如何使用遗传算法来解决旅行商问题,并给出相应的C语言代码实现。
我们将介绍旅行商问题的数学模型,然后简要介绍遗传算法的原理,最后给出C语言代码实现。
旅行商问题是指一个旅行商要拜访n个城市,恰好拜访每个城市一次,并返回出发城市,要求总路程最短。
数学上可以用一个n*n的距离矩阵d[i][j]表示城市i到城市j的距离,问题可以形式化为求解一个排列p={p1,p2,...,pn},使得目标函数f(p)=Σd[p[i]][p[i+1]]+d[p[n]][p[1]]最小。
这个问题是一个组合优化问题,其搜索空间是一个n维的离散空间。
遗传算法是一种基于生物进化过程的优化算法,主要包括选择、交叉、变异等操作。
在使用遗传算法解决旅行商问题时,可以将每个排列p看作一个个体,目标函数f(p)看作个体的适应度,通过选择、交叉和变异等操作来搜索最优解。
以下是遗传算法解决旅行商问题的C语言代码实现:1. 我们需要定义城市的距离矩阵和其他相关参数,例如城市的数量n,种裙大小pop_size,交叉概率pc,变异概率pm等。
2. 我们初始化种裙,即随机生成pop_size个排列作为初始种裙。
3. 我们进入遗传算法的迭代过程。
在每一代中,我们首先计算种裙中每个个体的适应度,然后通过选择、交叉和变异操作来更新种裙。
4. 选择操作可以采用轮盘赌选择法,即根据个体的适应度来进行选择,适应度越高的个体被选中的概率越大。
5. 交叉操作可以采用部分映射交叉方法,即随机选择两个个体,然后随机选择一个交叉点,将交叉点之后的基因片段进行交换。
6. 变异操作可以采用变异率为pm的单点变异方法,即随机选择一个个体和一个位置,将该位置的基因值进行随机变异。
7. 我们重复进行迭代操作,直到达到停止条件(例如达到最大迭代次数或者适应度达到阈值)。
using System;using System.IO;using System.Collections;using System.Collections.Generic;using System.Text;using ponentModel;using System.Data;using System.Data.OleDb;namespace ConsoleApplication1{public class Genetic_Algorithm{Random rand=new Random();int MaxTime;//最大运行时间int popsize;//种群数量int ChromosomeLength;//染色体长度double CrossRate;//交叉率double MutateRate;//变异率double[] f;//适应度值int[] selected;//定义selected数组,用于表示需要进行交叉操作的染色体序号double[] wheel;//轮盘int[,] pregeneration;//上一代int[,] nextgeneration;//下一代int[] Best;//定义当前最优解int convergence;//定义当前最优解的已持续代数int[,] timeconstrait;public Genetic_Algorithm(int populationsize, int chromolength)//GA--构造函数,变量初始化{rand = new Random(lisecond);MaxTime = 50;popsize=populationsize;ChromosomeLength = chromolength;CrossRate = 0.8;MutateRate = 0.2;f = new double[2*popsize];selected = new int[popsize];wheel = new double[popsize + 1];pregeneration = new int[popsize, ChromosomeLength];//当前的染色体种群nextgeneration = new int[popsize, ChromosomeLength];//下一代(子代)染色体种群Best = new int[ChromosomeLength];convergence = 1;timeconstrait = new int[20, 2] { { 2, 6 }, { 1, 2 }, { 3, 4 }, { 1, 4 }, { 4, 7 }, { 3, 5 }, { 2, 6 }, { 3, 5 }, { 1, 4 }, { 3, 7 }, { 5, 7 }, { 2, 7 }, { 2, 4 }, { 4, 5 }, { 2, 5 }, { 4, 6 }, { 3, 5 }, { 1, 4 }, { 1, 5 }, { 3, 6 } };}public void RunGA()//运行{int i;CreateFirstPop();//产生初始种群i = 0;bool quit = true;while (quit){for (; i < MaxTime; i++){Console.WriteLine("The {0}th Generation..........", i + 1);CalFitness(ref pregeneration, popsize);//计算适应值PrintResult();//输出每步的结果WheelSelect();//此步确定了selected[i]的值CreateNextGeneration();//产生子代,包括被选择为selected[i]的染色体的交叉,还有变异ProduceNext();}Console.WriteLine("Press 'q' to quit, press Enter to continue.....");if (Console.Read() == 'q'){quit = false;}else{MaxTime += 50;}}}void CreateFirstPop()//产生初始种群{Console.WriteLine("Creating first generation..........\n");int i,j,r;for(i=0;i<popsize;i++){for(j=0;j<ChromosomeLength;j++){r=rand.Next(1,11);pregeneration[i, j] = r;}}}void CreateNextGeneration()//产生下一代种群(经交叉、变异){int i;for (i = 0; i < popsize; i+=2){Crossover(selected[i], selected[i + 1], i, i + 1);//将序号为selected[i]和selected[i + 1]的染色体进行交叉,产生的子代放在pregeneration中i和i+1的位置}Mutation(ref nextgeneration);//变异}void CalFitness(ref int[,] curgeneration,int number)//计算适应度值的函数{for (int i = 0; i < number; i++){double fitness = 0;for (int j = 0; j < ChromosomeLength; j++){fitness += Math.Abs(curgeneration[i, j]-j-1);}f[i] = fitness;}}void FindMax(ref double[] f, out int max)//寻找数组中最大值{int i;max = 0;for (i = 1; i < popsize; i++){if (f[i] > f[max]){max = i;}}}void FindMin(ref double[] f, out int min)//寻找数组中最小值{int i;min = 0;for (i = 1; i < popsize; i++){if (f[i] < f[min]){min = i;}}}void WheelSelect() //轮盘选择popsize个染色体(可重复),并将序号放入selected[]中,作为交叉的染色体{int i,j ,r;double sum;wheel[0] = 0; sum = 0;for (i = 0; i < popsize; i++){sum += f[i];wheel[i + 1] = wheel[i] + f[i];}for (i = 0; i < popsize; i++){r = rand.Next((int)sum);for (j = 0; j < popsize; j++){if (r > wheel[j] && r < wheel[j + 1]){selected[i] = j;break;}}}}void Crossover(int p1, int p2, int c1, int c2)//交叉==>将序号为selected[i]和selected[i + 1](这里形参是p1,p2)的染色体进行交叉,产生的子代放在pregeneration中i和i+1(这里形参是c1,c2)的位置{double dr = rand.NextDouble();if (dr < CrossRate){int[] covering_code = new int[ChromosomeLength];for (int i = 0; i < ChromosomeLength; i++)covering_code[i] = rand.Next(0, 2);for (int i = 0; i < ChromosomeLength; i++){if (covering_code[i] == 0){nextgeneration[c1, i] = pregeneration[p1, i];nextgeneration[c2, i] = pregeneration[p2, i];}else{nextgeneration[c1, i] = pregeneration[p2, i];nextgeneration[c2, i] = pregeneration[p1, i];}}}else{for (int i = 0; i < ChromosomeLength; i++){nextgeneration[c1, i] = pregeneration[p1, i];nextgeneration[c2, i] = pregeneration[p2, i];}}}void Mutation(ref int[,] curgeneration)//变异{int is_not_mutation;double dr;for (int i = 0; i < popsize; i++){dr = rand.NextDouble();if (dr < MutateRate){for (int j = 0; j < ChromosomeLength; j++){is_not_mutation = rand.Next(0, 2);if (is_not_mutation == 1)curgeneration[i, j] = rand.Next(1, 11);}}}}void PrintResult()//计算每次迭代后种群中最优解及其适应度值,平均适应值 {int i,j;int min;double average;average = 0;for (i = 0; i < popsize; i++){average += f[i];}average = (double) average / popsize;Console.Write("Average profit is {0}\n", average);FindMin(ref f, out min);//计算稳定的次数for (j = 0; j < ChromosomeLength; j++){if (pregeneration[min, j] != Best[j]){convergence = 1;goto G2;}}convergence++;G2:for (j = 0; j < ChromosomeLength; j++){Best[j] = pregeneration[min, j];}//打印相关的数据Console.Write("染色体 ");for (j = 0; j < ChromosomeLength; j++){Console.Write(pregeneration[min, j] + ",");}Console.WriteLine("");Console.WriteLine("综合目标 {0} of individual ", f[min]);Console.WriteLine("已经稳定的代数 {0} of individual ",convergence);Console.WriteLine("");}void ProduceNext()//选择==>父代和子代中popsize个最优的解进入下一代{int[,] temgeneration=new int [2*popsize,ChromosomeLength];//定义临时种群,用来将父代和子代放在一起,进行选优//将父代放入临时种群for (int i = 0; i <= popsize - 1; i++){for (int j = 0; j <= ChromosomeLength - 1; j++){temgeneration[i, j] = pregeneration[i, j];}}//将子代放入临时种群for (int i = 0; i <= popsize - 1; i++){for (int j = 0; j <= ChromosomeLength - 1; j++){temgeneration[i + popsize, j] = nextgeneration[i, j];}}CalFitness(ref temgeneration, popsize * 2);//计算临时种群(父代和子代)的各染色体适应值int []tem=new int [ChromosomeLength];//定义临时染色体,用来染色体排序时的交换...//根据临时种群(父代和子代)的各染色体适应值,进行排序for (int i = 0; i < 2*popsize - 1; i++){for (int j = i + 1; j <= 2 * popsize - 1; j++){if (f[i] > f[j]){double tem_f = f[i];f[i] = f[j];f[j] = tem_f;for (int k = 0; k < ChromosomeLength; k++){tem[k] = temgeneration[i, k];temgeneration[i, k] = temgeneration[j, k];temgeneration[j, k] = tem[k];}}}}//取临时种群中前popsize个好的染色体作为下一代种群,并将子代变为父代for (int i = 0; i <= popsize - 1; i++){for (int j = 0; j <= ChromosomeLength - 1; j++){pregeneration[i, j] = temgeneration[i, j];}}}}class Program{static void Main(string[] args){int chromosomelength = 10;int populationsize = 300;int cycle = 5;Console.WriteLine("Press Enter to start running Genetic Algorithm");Console.ReadKey();Genetic_Algorithm GA = new Genetic_Algorithm(populationsize, chromosomelength); GA.RunGA();}}}。
解TSP问题的遗传算法C语言程序#include<stdio.h>#include<stdlib.h>#include<math.h>#include<alloc.h>#include<conio.h>#include<float.h>#include<time.h>#include<graphics.h>#include<bios.h>#define maxpop 100#define maxstring 100struct pp{unsigned char chrom[maxstring];float x,fitness;unsigned int parent1,parent2,xsite;};struct pp *oldpop,*newpop,*p1;unsigned int popsize,lchrom,gem,maxgen,co_min,jrand;unsigned int nmutation,ncross,jcross,maxpp,minpp,maxxy;floatpcross,pmutation,sumfitness,avg,max,min,seed,maxold,oldrand[maxstring];unsigned char x[maxstring],y[maxstring]; float*dd,ff,maxdd,refpd,fm[201]; FILE *fp,*fp1;float objfunc(float);void statistics();int select();int flip(float);int crossover();void generation();void initialize();void report();float decode();void crtinit();void inversion();float random1();void randomize1();main(){unsigned int gen,k,j,tt;char fname[10];float ttt;clrscr();co_min=0;if((oldpop=(struct pp *)farmalloc(maxpop*sizeof(struct pp)))==NULL) {printf("memory requst fail!\n");exit(0);} if((dd=(float*)farmalloc(maxstring*maxstring*sizeof(float)))==NULL){printf("memory requst fail!\n");exit(0);} if((newpop=(struct pp *)farmalloc(maxpop*sizeof(struct pp)))==NULL){printf("memory requst fail!\n");exit(0);} if((p1=(struct pp*)farmalloc(sizeof(struct pp)))==NULL){printf("memory requst fail!\n");exit(0);} for(k=0;k<maxpop;k++) oldpop[k].chrom[0]='\0'; for(k=0;k<maxpop;k++) newpop[k].chrom[0]='\0'; printf("Enter Result Data Filename:"); gets(fname);if((fp=fopen(fname,"w+"))==NULL){printf("cannot open file\n");exit(0);}gen=0;randomize();initialize();fputs("this is result of the TSP problem:",fp);fprintf(fp,"city: %2d psize: %3d Ref.TSP_path:%f\n",lchrom,popsize,refpd);fprintf(fp,"Pc: %f Pm: %f Seed: %f\n",pcross,pmutation,seed);fprintf(fp,"X site:\n");for(k=0;k<lchrom;k++){if((k%16)==0) fprintf(fp,"\n"); fprintf(fp,"%5d",x[k]);}fprintf(fp,"\n Y site:\n"); for(k=0;k<lchrom;k++){if((k%16)==0) fprintf(fp,"\n"); fprintf(fp,"%5d",y[k]);}fprintf(fp,"\n");crtinit();statistics(oldpop);report(gen,oldpop);getch();maxold=min;fm[0]=100.0*oldpop[maxpp].x/ff; do {gen=gen+1;generation();statistics(oldpop);if(max>maxold){maxold=max;co_min=0;}fm[gen%200]=100.0*oldpop[maxpp].x/ff; report(gen,oldpop);gotoxy(30,25);ttt=clock()/18.2;tt=ttt/60;printf("Run Clock: %2d: %2d: %4.2f",tt/60,tt%60,ttt-tt*60.0);printf("Min=%6.4fNm:%d\n",min,co_min); }while((gen<100)&&!bioskey(1)); printf("\n gen= %d",gen);do{gen=gen+1;generation();statistics(oldpop);if(max>maxold){maxold=max;co_min=0;}fm[gen%200]=100.0*oldpop[maxpp].x/ff; report(gen,oldpop);if((gen%100)==0)report(gen,oldpop); gotoxy(30,25);ttt=clock()/18.2;tt=ttt/60;printf("Run Clock: %2d: %2d: %4.2f",tt/60,tt%60,ttt-tt*60.0);printf("Min=%6.4fNm:%d\n",min,co_min); }while((gen<maxgen)&&!bioskey(1));getch();for(k=0;k<lchrom;k++) {if((k%16)==0)fprintf(fp,"\n");fprintf(fp,"%5d",oldpop[maxpp].chrom[k]);}fprintf(fp,"\n");fclose(fp);farfree(dd);farfree(p1);farfree(oldpop);farfree(newpop);restorecrtmode();exit(0);}/*%%%%%%%%%%%%%%%%*/float objfunc(float x1) {float y;y=100.0*ff/x1;return y;}/*&&&&&&&&&&&&&&&&&&&*/void statistics(pop) struct pp *pop;{int j;sumfitness=pop[0].fitness; min=pop[0].fitness; max=pop[0].fitness; maxpp=0;minpp=0;for(j=1;j<popsize;j++) {sumfitness=sumfitness+pop[j].fitness;if(pop[j].fitness>max){max=pop[j].fitness;maxpp=j;}if(pop[j].fitness<min){min=pop[j].fitness;minpp=j;}}avg=sumfitness/(float)popsize;}/*%%%%%%%%%%%%%%%%%%%%*/void generation(){unsigned int k,j,j1,j2,i1,i2,mate1,mate2;float f1,f2;j=0;do{mate1=select();pp:mate2=select();if(mate1==mate2)goto pp;crossover(oldpop[mate1].chrom,oldpop[mate2].chrom,j);newpop[j].x=(float)decode(newpop[j].chrom);newpop[j].fitness=objfunc(newpop[j].x); newpop[j].parent1=mate1;newpop[j].parent2=mate2;newpop[j].xsite=jcross;newpop[j+1].x=(float)decode(newpop[j+1].chrom);newpop[j+1].fitness=objfunc(newpop[j+1].x); newpop[j+1].parent1=mate1;newpop[j+1].parent2=mate2;newpop[j+1].xsite=jcross;if(newpop[j].fitness>min){for(k=0;k<lchrom;k++)oldpop[minpp].chrom[k]=newpop[j].chrom[k];oldpop[minpp].x=newpop[j].x;oldpop[minpp].fitness=newpop[j].fitness;co_min++;return;}if(newpop[j+1].fitness>min){for(k=0;k<lchrom;k++)oldpop[minpp].chrom[k]=newpop[j+1].chrom[k];oldpop[minpp].x=newpop[j+1].x;oldpop[minpp].fitness=newpop[j+1].fitness;co_min++;return;}j=j+2;}while(j<popsize);}/*%%%%%%%%%%%%%%%%%*/void initdata(){unsigned int ch,j;clrscr();printf("-----------------------\n");printf("A SGA\n");printf("------------------------\n");/*pause();*/clrscr();printf("*******SGA DATA ENTRY AND INITILIZATION *******\n");printf("\n");printf("input pop size");scanf("%d",&popsize); printf("input chrom length");scanf("%d",&lchrom); printf("input maxgenerations");scanf("%d",&maxgen); printf("input crossoverprobability");scanf("%f",&pcross); printf("input mutationprob");scanf("%f",&pmutation); randomize1();clrscr();nmutation=0;ncross=0;}/*%%%%%%%%%%%%%%%%%%%%*/void initreport(){int j,k;printf("pop size=%d\n",popsize);printf("chromosome length=%d\n",lchrom);printf("maxgen=%d\n",maxgen);printf("pmutation=%f\n",pmutation); printf("pcross=%f\n",pcross);printf("initial generation statistics\n"); printf("ini pop maxfitness=%f\n",max); printf("ini pop avr fitness=%f\n",avg); printf("ini pop min fitness=%f\n",min); printf("ini pop sum fit=%f\n",sumfitness); } void initpop(){unsigned char j1;unsigned int k5,i1,i2,j,i,k,j2,j3,j4,p5[maxstring];float f1,f2;j=0;for(k=0;k<lchrom;k++)oldpop[j].chrom[k]=k;for(k=0;k<lchrom;k++)p5[k]=oldpop[j].chrom[k];randomize();for(;j<popsize;j++){j2=random(lchrom);for(k=0;k<j2+20;k++){j3=random(lchrom);j4=random(lchrom);j1=p5[j3];p5[j3]=p5[j4];p5[j4]=j1;}for(k=0;k<lchrom;k++)oldpop[j].chrom[k]=p5[k]; }for(k=0;k<lchrom;k++)for(j=0;j<lchrom;j++)dd[k*lchrom+j]=hypot(x[k]-x[j],y[k]-y[j]);for(j=0;j<popsize;j++) {oldpop[j].x=(float)decode(oldpop[j].chrom); oldpop[j].fitness=objfunc(oldpop[j].x);oldpop[j].parent1=0;oldpop[j].parent2=0;oldpop[j].xsite=0;}}/*&&&&&&&&&&&&&&&&&*/void initialize(){int k,j,minx,miny,maxx,maxy; initdata();minx=0;miny=0;maxx=0;maxy=0;for(k=0;k<lchrom;k++){x[k]=rand();if(x[k]>maxx)maxx=x[k]; if(x[k]<minx)minx=x[k]; y[k]=rand();if(y[k]>maxy)maxy=y[k]; if(y[k]<miny)miny=y[k]; }if((maxx-minx)>(maxy-miny)){maxxy=maxx-minx;}else {maxxy=maxy-miny;}maxdd=0.0;for(k=0;k<lchrom;k++)for(j=0;j<lchrom;j++){dd[k*lchrom+j]=hypot(x[k]-x[j],y[k]-y[j]);if(maxdd<dd[k*lchrom+j])maxdd=dd[k*lchrom+j];}refpd=dd[lchrom-1];for(k=0;k<lchrom;k++)refpd=refpd+dd[k*lchrom+k+2]; for(j=0;j<lchrom;j++)dd[j*lchrom+j]=4.0*maxdd; ff=(0.765*maxxy*pow(lchrom,0.5)); minpp=0; min=dd[lchrom-1];for(j=0;j<lchrom-1;j++){if(dd[lchrom*j+lchrom-1]<min){min=dd[lchrom*j+lchrom-1];minpp=j;}}initpop();statistics(oldpop);initreport();}/*&&&&&&&&&&&&&&&&&&*/void report(int l,struct pp *pop){int k,ix,iy,jx,jy;unsigned int tt;float ttt;cleardevice();gotoxy(1,1);printf("city:%4d para_size:%4d maxgen:%4d ref_tour:%f\n",lchrom,popsize,maxgen,refpd);printf("ncross:%4d Nmutation:%4d Rungen:%4d AVG=%8.4f MIN=%8.4f\n\n",ncross,nmutation,l,avg,min);printf("inpath:%6.4f Minpath length:%10.4f Ref_co_tour:%f\n",pop[maxpp].x/maxxy,pop[maxpp].x,ff); printf("Co_minpath:%6.4f Maxfit:%10.8f",100.0*pop[maxpp].x/ff,pop[maxpp].fitness); ttt=clock()/18.2;tt=ttt/60;printf("Run clock:%2d:%2d:%4d.2f\n",tt/60,tt%60,ttt-tt*60.0); setcolor(1%15+1);for(k=0;k<lchrom-1;k++){ix=x[pop[maxpp].chrom[k]];iy=y[pop[maxpp].chrom[k]]+110;jx=x[pop[maxpp].chrom[k+1]];jy=y[pop[maxpp].chrom[k+1]]+110;line(ix,iy,jx,jy);putpixel(ix,iy,RED);}ix=x[pop[maxpp].chrom[0]];iy=y[pop[maxpp].chrom[0]]+110;jx=x[pop[maxpp].chrom[lchrom-1]];jy=y[pop[maxpp].chrom[lchrom-1]]+110; line(ix,iy,jx,jy); putpixel(jx,jy,RED);setcolor(11);outtextxy(ix,iy,"*");setcolor(12);for(k=0;k<1%200;k++){ix=k+280;iy=366-fm[k]/3;jx=ix+1;jy=366-fm[k+1]/3;line(ix,iy,jx,jy);putpixel(ix,iy,RED);}printf("GEN:%3d",l);printf("Minpath:%f Maxfit:%f",pop[maxpp].x,pop[maxpp].fitness); printf("Clock:%2d:%2d:%4.2f\n",tt/60,tt%60,ttt-tt*60.0);}/*###############*/float decode(unsigned char *pp) {int j,k,l;float tt;tt=dd[pp[0]*lchrom+pp[lchrom-1]]; for(j=0;j<lchrom-1;j++){tt=tt+dd[pp[j]*lchrom+pp[j+1]];} l=0;for(k=0;k<lchrom-1;k++)for(j=k+1;j<lchrom;j++){if(pp[j]==pp[k])l++;}return tt+4*l*maxdd;}/*%%%%%%%%%%%%%%%%%%*/ void crtinit(){int driver,mode;struct palettetype p;driver=DETECT;mode=0;initgraph(&driver,&mode,""); cleardevice();}/*$$$$$$$$$$$$$$$$$$$$*/ int select(){double rand1,partsum; float r1;int j;partsum=0.0;j=0;rand1=random1()*sumfitness; do{partsum=partsum+oldpop[j].fitness;j=j+1;}while((partsum<rand1)&&(j<popsize));return j-1;}/*$$$$$$$$$$$$$$$*/int crossover(unsigned char *parent1,unsigned char *parent2,int k5) {int k,j,mutate,i1,i2,j5;int j1,j2,j3,s0,s1,s2; unsigned charjj,ts1[maxstring],ts2[maxstring];float f1,f2;s0=0;s1=0;s2=0;if(flip(pcross)){jcross=random(lchrom-1); j5=random(lchrom-1); ncross=ncross+1;if(jcross>j5){k=jcross;jcross=j5;j5=k;}}else jcross=lchrom; if(jcross!=lchrom) {s0=1;k=0;for(j=jcross;j<j5;j++) {ts1[k]=parent1[j]; ts2[k]=parent2[j]; k++; }j3=k;for(j=0;j<lchrom;j++) {j2=0;while((parent2[j]!=ts1[j2])&&(j2<k)){j2++;}if(j2==k){ts1[j3]=parent2[j];j3++;}}j3=k;for(j=0;j<lchrom;j++){j2=0;while((parent1[j]!=ts2[j2])&&(j2<k)){j2++;}if(j2==k){ts2[j3]=parent1[j];j3++;}}for(j=0;j<lchrom;j++){newpop[k5].chrom[j]=ts1[j];newpop[k5+1].chrom[j]=ts2[j]; }}else{for(j=0;j<lchrom;j++){newpop[k5].chrom[j]=parent1[j]; newpop[k5+1].chrom[j]=parent2[j]; } mutate=flip(pmutation);if(mutate){s1=1;nmutation=nmutation+1;for(j3=0;j3<200;j3++){j1=random(lchrom);j=random(lchrom);jj=newpop[k5].chrom[j];newpop[k5].chrom[j]=newpop[k5].chrom[j1];newpop[k5].chrom[j1]=jj;}}mutate=flip(pmutation);if(mutate){s2=1;nmutation=nmutation+1;for(j3=0;j3<100;j3++){j1=random(lchrom);j=random(lchrom);jj=newpop[k5+1].chrom[j];newpop[k5+1].chrom[j]=newpop[k5+1].chrom[j1];newpop[k5+1].chrom[j1]=jj;}}}j2=random(2*lchrom/3);for(j=j2;j<j2+lchrom/3-1;j++)for(k=0;k<lchrom;k++){if(k==j)continue;if(k>j){i2=k;i1=j;}else{i1=k;i2=j;}f1=dd[lchrom*newpop[k5].chrom[i1]+newpop[k5].chrom[i2]]; f1=f1+dd[lchrom*newpop[k5].chrom[(i1+1)%lchrom]+newpop[k5].chrom[(i2+1)%lchrom]];f2=dd[lchrom*newpop[k5].chrom[i1]+newpop[k5].chrom[(i1+1)%lchrom]];f2=f2+dd[lchrom*newpop[k5].chrom[i2]+newpop[k5].chrom[(i2+1)%lchrom]];if(f1<f2){inversion(i1,i2,newpop[k5].chrom);}}j2=random(2*lchrom/3);for(j=j2;j<j2+lchrom/3-1;j++)for(k=0;k<lchrom;k++){if(k==j)continue;if(k>j){i2=k;i1=j;}else{i1=k;i2=j;}f1=dd[lchrom*newpop[k5+1].chrom[i1]+newpop[k5+1].chrom[i2]];f1=f1+dd[lchrom*newpop[k5+1].chrom[(i1+1)%lchrom]+newpop[k5+1].chrom[(i2+1)%lchrom]];f2=dd[lchrom*newpop[k5+1].chrom[i1]+newpop[k5+1].chrom[(i1+1)%lchrom]];f2=f2+dd[lchrom*newpop[k5+1].chrom[i2]+newpop[k5+1].chrom[(i2+1)%lchrom]];if(f1<f2){inversion(i1,i2,newpop[k5+1].chrom);} }return 1;}/*$$$$$$$$$$$$$$$*/void inversion(unsigned int k,unsigned int j,unsigned char *ss) {unsigned int l1,i;unsigned char tt;l1=(j-k)/2;for(i=0;i<l1;i++){tt=ss[k+i+1];ss[k+i+1]=ss[j-i];ss[j-i]=tt;}}/*%%%%%%%%%%%%%%%*/void randomize1(){int i;randomize();for(i=0;i<lchrom;i++) oldrand[i]=random(30001)/30000.0;jrand=0;}/*%%%%%%%%%%%*/float random1(){jrand=jrand+1;if(jrand>=lchrom){jrand=0;randomize1();}return oldrand[jrand]; }/*%%%%%%%%%%*/int flip(float probability) {float ppp;ppp=random(20001)/20000.0; if(ppp<=probability)return 1; return 0;}%TSP问题(又名:旅行商问题,货郎担问题)遗传算法通用matlab程序 %D是距离矩阵,n为种群个数,建议取为城市个数的1~2倍, %C为停止代数,遗传到第 C 代时程序停止,C的具体取值视问题的规模和耗费的时间而定%m为适应值归一化淘汰加速指数 ,最好取为1,2,3,4 ,不宜太大 %alpha为淘汰保护指数,可取为0~1之间任意小数,取1时关闭保护功能,最好取为0.8~1.0 %R为最短路径,Rlength为路径长度function [R,Rlength]=geneticTSP(D,n,C,m,alpha)[N,NN]=size(D);farm=zeros(n,N);%用于存储种群for i=1:nfarm(i,:)=randperm(N);%随机生成初始种群endR=farm(1,:);%存储最优种群len=zeros(n,1);%存储路径长度fitness=zeros(n,1);%存储归一化适应值counter=0;while counter<Cfor i=1:nlen(i,1)=myLength(D,farm(i,:));%计算路径长度endmaxlen=max(len);minlen=min(len);fitness=fit(len,m,maxlen,minlen);%计算归一化适应值rr=find(len==minlen);R=farm(rr(1,1),:);%更新最短路径FARM=farm;%优胜劣汰,nn记录了复制的个数nn=0;for i=1:nif fitness(i,1)>=alpha*rand nn=nn+1;FARM(nn,:)=farm(i,:);endendFARM=FARM(1:nn,:);[aa,bb]=size(FARM);%交叉和变异while aa<nif nn<=2nnper=randperm(2);elsennper=randperm(nn);endA=FARM(nnper(1),:);B=FARM(nnper(2),:);[A,B]=intercross(A,B); FARM=[FARM;A;B]; [aa,bb]=size(FARM);endif aa>nFARM=FARM(1:n,:);%保持种群规模为nendfarm=FARM;clear FARMcounter=counter+1endRlength=myLength(D,R);function [a,b]=intercross(a,b) L=length(a); if L<=10%确定交叉宽度W=1;elseif ((L/10)-floor(L/10))>=rand&&L>10W=ceil(L/10);elseW=floor(L/10);endp=unidrnd(L-W+1);%随机选择交叉范围,从p到p+W for i=1:W%交叉x=find(a==b(1,p+i-1)); y=find(b==a(1,p+i-1)); [a(1,p+i-1),b(1,p+i-1)]=exchange(a(1,p+i-1),b(1,p+i-1));[a(1,x),b(1,y)]=exchange(a(1,x),b(1,y));endfunction [x,y]=exchange(x,y) temp=x;x=y;y=temp;% 计算路径的子程序function len=myLength(D,p) [N,NN]=size(D);len=D(p(1,N),p(1,1)); for i=1:(N-1)len=len+D(p(1,i),p(1,i+1));end%计算归一化适应值子程序function fitness=fit(len,m,maxlen,minlen) fitness=len;for i=1:length(len)fitness(i,1)=(1-((len(i,1)-minlen)/(maxlen-minlen+0.000001))).^m;end。
// GA.cpp : Defines the entry point for the console application.///*这是一个非常简单的遗传算法源代码,是由Denis Cormier (North Carolina State University)开发的,Sita S.Raghavan (University of North Carolina at Charlotte)修正。
代码保证尽可能少,实际上也不必查错。
对一特定的应用修正此代码,用户只需改变常数的定义并且定义“评价函数”即可。
注意代码的设计是求最大值,其中的目标函数只能取正值;且函数值和个体的适应值之间没有区别。
该系统使用比率选择、精华模型、单点杂交和均匀变异。
如果用Gaussian变异替换均匀变异,可能得到更好的效果。
代码没有任何图形,甚至也没有屏幕输出,主要是保证在平台之间的高可移植性。
读者可以从, 目录coe/evol中的文件prog.c中获得。
要求输入的文件应该命名为‘gadata.txt’;系统产生的输出文件为‘galog.txt’。
输入的文件由几行组成:数目对应于变量数。
且每一行提供次序——对应于变量的上下界。
如第一行为第一个变量提供上下界,第二行为第二个变量提供上下界,等等。
*/#include <stdio.h>#include <stdlib.h>#include <math.h>/* Change any of these parameters to match your needs *///请根据你的需要来修改以下参数#define POPSIZE 50 /* population size 种群大小*/#define MAXGENS 1000 /* max. number of generations 最大基因个数*/const int NVARS = 3; /* no. of problem variables 问题变量的个数*/#define PXOVER 0.8 /* probability of crossover 杂交概率*/#define PMUTATION 0.15 /* probability of mutation 变异概率*/#define TRUE 1#define FALSE 0int generation; /* current generation no. 当前基因个数*/int cur_best; /* best individual 最优个体*/FILE *galog; /* an output file 输出文件指针*/struct genotype /* genotype (GT), a member of the population 种群的一个基因的结构体类型*/{double gene[NVARS]; /* a string of variables 变量*/double fitness; /* GT's fitness 基因的适应度*/double upper[NVARS]; /* GT's variables upper bound 基因变量的上界*/ double lower[NVARS]; /* GT's variables lower bound 基因变量的下界*/ double rfitness; /* relative fitness 比较适应度*/double cfitness; /* cumulative fitness 积累适应度*/};struct genotype population[POPSIZE+1]; /* population 种群*/struct genotype newpopulation[POPSIZE+1]; /* new population; 新种群*//* replaces the old generation *///取代旧的基因/* Declaration of procedures used by this genetic algorithm *///以下是一些函数声明void initialize(void);double randval(double, double);void evaluate(void);void keep_the_best(void);void elitist(void);void select(void);void crossover(void);void Xover(int,int);void swap(double *, double *);void mutate(void);void report(void);/***************************************************************/ /* Initialization function: Initializes the values of genes *//* within the variables bounds. It also initializes (to zero) *//* all fitness values for each member of the population. It *//* reads upper and lower bounds of each variable from the *//* input file `gadata.txt'. It randomly generates values *//* between these bounds for each gene of each genotype in the *//* population. The format of the input file `gadata.txt' is *//* var1_lower_bound var1_upper bound *//* var2_lower_bound var2_upper bound ... *//***************************************************************/void initialize(void){FILE *infile;int i, j;double lbound, ubound;if ((infile = fopen("gadata.txt","r"))==NULL){fprintf(galog,"\nCannot open input file!\n");exit(1);}/* initialize variables within the bounds *///把输入文件的变量界限输入到基因结构体中for (i = 0; i < NVARS; i++){fscanf(infile, "%lf",&lbound);fscanf(infile, "%lf",&ubound);for (j = 0; j < POPSIZE; j++){population[j].fitness = 0;population[j].rfitness = 0;population[j].cfitness = 0;population[j].lower[i] = lbound;population[j].upper[i]= ubound;population[j].gene[i] = randval(population[j].lower[i],population[j].upper[i]);}}fclose(infile);}/***********************************************************/ /* Random value generator: Generates a value within bounds *//***********************************************************/ //随机数产生函数double randval(double low, double high){double val;val = ((double)(rand()%1000)/1000.0)*(high - low) + low;return(val);}/*************************************************************/ /* Evaluation function: This takes a user defined function. *//* Each time this is changed, the code has to be recompiled. *//* The current function is: x[1]^2-x[1]*x[2]+x[3] *//*************************************************************/ //评价函数,可以由用户自定义,该函数取得每个基因的适应度void evaluate(void){int mem;int i;double x[NVARS+1];for (mem = 0; mem < POPSIZE; mem++){for (i = 0; i < NVARS; i++)x[i+1] = population[mem].gene[i];population[mem].fitness = (x[1]*x[1]) - (x[1]*x[2]) + x[3];}}/***************************************************************/ /* Keep_the_best function: This function keeps track of the *//* best member of the population. Note that the last entry in *//* the array Population holds a copy of the best individual *//***************************************************************/ //保存每次遗传后的最佳基因void keep_the_best(){int mem;int i;cur_best = 0;/* stores the index of the best individual *///保存最佳个体的索引for (mem = 0; mem < POPSIZE; mem++){if (population[mem].fitness > population[POPSIZE].fitness){cur_best = mem;population[POPSIZE].fitness = population[mem].fitness;}}/* once the best member in the population is found, copy the genes *///一旦找到种群的最佳个体,就拷贝他的基因for (i = 0; i < NVARS; i++)population[POPSIZE].gene[i] = population[cur_best].gene[i];}/****************************************************************/ /* Elitist function: The best member of the previous generation *//* is stored as the last in the array. If the best member of *//* the current generation is worse then the best member of the *//* previous generation, the latter one would replace the worst *//* member of the current population *//****************************************************************///搜寻杰出个体函数:找出最好和最坏的个体。
/*本程序试用遗传算法来解决Rosenbrock函数的全局最大值计算问题:max f(x1,x2)=100(x1^2-x2^2)^2+(1-x1)^2s.t.-2.048≤xi≤2.048(i=1,2)*/#include<iostream>#include<time.h>#include<stdlib.h>#include<cmath>using namespace std;const int M=8,T=2;//M群体大小,pc交叉概率,pm变异概率,T终止代数const double pc=0.6,pm=0.01;struct population//定义群体结构{int x[20];double x1,x2;double fit;double sumfit;}p[M];void initial(population*);//初始化函数void evaluefitness(population*);//计算适应度void select(population*);//选择复制函数void crossover(population*);//交叉函数void mutation(population*);//变异函数void decoding(population*);//解码函数void print(population*);//显示函数int main()//遗传算法主函数{int gen=0;initial(&p[0]);//随机获得初始解cout<<"initialed!"<<endl;print(&p[0]);decoding(&p[0]);//先解码cout<<"decoded!"<<endl;print(&p[0]);evaluefitness(&p[0]);//计算适应值与累计适值cout<<"evalued!"<<endl;print(&p[0]);while(gen<=T){cout<<"gen="<<gen+1<<endl;select(&p[0]);decoding(&p[0]);evaluefitness(&p[0]);cout<<"selected!"<<endl;print(&p[0]);crossover(&p[0]);decoding(&p[0]);evaluefitness(&p[0]);cout<<"crossovered!"<<endl;print(&p[0]);mutation(&p[0]);decoding(&p[0]);evaluefitness(&p[0]);cout<<"mutated!"<<endl;print(&p[0]);gen++;}decoding(&p[0]);evaluefitness(&p[0]);cout<<"最后得出的满意解为:"<<endl;for(int i=0;i<M;i++)cout<<"x1:"<<p[i].x1<<"x2:"<<p[i].x2<<"值:"<<p[i].fit<<endl;return0;}/*****************************初始化函数*****************************/int rand01()//用于随机取0或1的函数{int r;float q;q=rand()/(RAND_MAX+0.0);if(q<0.5)r=0;else r=1;return r;}void initial(population*t)//群体初始化函数{int j;population*po;srand(time(0));for(po=t;po<t+M;po++)for(j=0;j<20;j++)(*po).x[j]=rand01();}/*************************计算适应值函数*********************************/ void evaluefitness(population*t)//计算适应值函数{double f,x1,x2,temp=0.0;population*po,*po2;for(po=t;po<t+M;po++){x1=(*po).x1;x2=(*po).x2;f=100.0*(x1*x1-x2*x2)*(x1*x1-x2*x2)+(1.0-x1)*(1.0-x1);(*po).fit=f;}for(po=t;po<t+M;po++)//计算累计适应值{for(po2=t;po2<=po;po2++)temp=temp+(*po2).fit;(*po).sumfit=temp;temp=0.0;}}/**************************选择复制函数********************************/ double randab(double a,double b)//在区间(a,b)内生成一个随机数{double c,r;c=b-a;r=a+c*rand()/(RAND_MAX+1.0);return r;}void select(population*t)//选择算子函数{int i=0;population pt[M],*po;double s;srand(time(0));while(i<M){s=randab((*t).sumfit,(*(t+M-1)).sumfit);for(po=t;po<t+M;po++){if((*po).sumfit>=s){pt[i]=(*po);break;}else continue;}i++;}for(i=0;i<M;i++)//将复制后数据pt[M]转入p[M] for(int j=0;j<20;j++)p[i].x[j]=pt[i].x[j];}/***************************交叉函数*******************************/ void crossover(population*t)//交叉算子函数{population*po;double q;//用于存一个0到1的随机数int d,e,tem[20];//d存放从1到19的一个随机整数,用来确定交叉的位置//e存放从0到M的一个随机且与当前P[i]中i不同的整数,用来确定交叉的对象srand(time(0));for(po=t;po<t+M/2;po++){q=rand()/(RAND_MAX+0.0);if(q<pc){for(int j=0;j<M;j++)//运算M次,避免产生群体中某个体与自己交叉的情况{e=rand()%M;//随机确定交叉对象if(t+e!=po)break;}//不能重复d=1+rand()%19;//随机确定交叉位置for(int i=d;i<20;i++){tem[i]=(*po).x[i];(*po).x[i]=(*(t+e)).x[i];(*(t+e)).x[i]=tem[i];}}else continue;}}/***************************变异函数*******************************/void mutation(population*t)//变异算子函数{double q;//q用来存放针对每一个基因座产生的[0,1]的随机数population*po;srand(time(0));for(po=t;po<t+M;po++){int i=0;while(i<20){q=rand()/(RAND_MAX+0.0);if(q<pm)(*po).x[i]=1-(*po).x[i];i++;}}}/***************************解码函数*******************************/void decoding(population*t)//解码函数{population*po;int temp,s1=0,s2=0;float m,n,dit;n=ldexp(1,10);//n=2^10dit=4.096/(n-1);//dit=(U(max)-U(min))/n-1for(po=t;po<t+M;po++){for(int i=0;i<10;i++){temp=ldexp((*po).x[i],i);s1=s1+temp;}m=-2.048+s1*dit;(*po).x1=m;s1=0;for(int j=10;j<20;j++){temp=ldexp((*po).x[j],j-10);s2=s2+temp;}m=-2.048+s2*dit;(*po).x2=m;s2=0;}}/*******************************显示函数**************************************/ void print(population*t){population*po;for(po=t;po<t+M;po++){for(int j=0;j<20;j++){cout<<(*po).x[j];if((j+1)%5==0)cout<<"";}cout<<endl;cout<<(*po).x1<<""<<(*po).x2<<""<<(*po).fit<<""<<(*po).sumfit<<endl;}}。
计算智能作业三:遗传算法计算问题1.问题描述:求下述二元函数的最大值:222121),(m ax x x x x f +=S.t. }7,6,5,4,3,2,1{1∈x }7,6,5,4,3,2,1{2∈x2.程序结构:(1)变量:C :是一个1*6数组,每个数组里面是一个6位二进制数,它是遗传算法中的染色体。
new_c:每一轮的新变量c 。
first_c:初始群体矩阵。
sur_value :个体适应值的概率值,为0-1之间的数,所有概率值和为1。
survived :经过选择运算后产生的个体基因型组合。
intersect_c :经过交叉运算后产生的个体基因型组合。
mutation_c :经过变异运算后产生的个体基因型组合。
f :最后计算得到的最大值 (2)程序里面的方程function out = value_function( ci ):价值函数(自适应度函数),即222121),(x x x x f +=。
function [ sur_value ] = calc_value( c ):计算群体中每一个个体的适应度的值function survived = surviver( sur_value ):利用概率选择函数 function [ intersect_c ] = intersect( new_c ):交叉运算function [ mutation_c ,mutation_value] = mutation( intersect_c ):变异运算3.源程序(1)遗传算法的主程序主程序包括初始群体产生,最终结果展示,即各函数之间的调用关系。
个体编码遗传算法的运算对象是表示个体的符号串,所以必须把变量 x1, x2 编码为无符号二进制整数。
这个二进制整数位个体的基因型。
因为x1, x2 为 0 ~ 7之间的整数,所以分别用3位无符号二进制整数来表示,将它们连接在一起所组成的6位无符号二进制数就形成了个体的基因型,表示一个可行解。
遗传算法程序实现#include <stdlib.h>#include <stdio.h>#include <time.h>#include <math.h>#include "GA.h"unsigned seed=1;//产生一个不大于x的随机数double crandom(int x){seed++;srand((unsigned)(seed*time(NULL)));return(rand()%x);}//产生一个0~1的随机数double random(){seed++;srand((unsigned)(seed*time(NULL)));return (double)rand()/(double)RAND_MAX;}//产生(0.1,0.2,...,1)之间的一个随机数double crandom(void){double t;t=random();if((10*t-floor(10*t))>=0.5) return (floor(10*t)+1)/10;elsereturn(floor(10*t)/10);}//初始化种群void Initial_group(double group[M][N_para], double up_limit[N_para],double low_limit[N_para]){ double beta;int i,j;for (i=0;i<M;i++)for (j=0;j<N_para;j++){beta=crandom();group[i][j]=low_limit[j]+beta*(up_limit[j]-low_limit[j]);}}}//加载实时测试数据void Load_data(double realvalue[][4]){FILE *fp;float x;//changedif((fp=fopen("realtime\\Realdata.txt","r"))==NULL){printf("cannot open the file Realvalue.txt\n");exit(0);}for(int i=0;i<N_hit+N_Begin;i++){for(int j=0;j<4;j++)//修改了{fscanf(fp,"%f ",&x);if(i>=N_Begin)realvalue[i-N_Begin][j]=(double)x;//修改了}}fclose(fp);}//计算适应度值void Fit_calculate(double group[][N_para],double realvalue[][4],double fit_degree[],int n){int i;//double Mcar,m1,r1,r2,L,J1,J2,c1,c2,b;double mcar,m1,l1,J1,b,g,f1,eks,eksd,theta1,theta1d,h;double x[4],x_temp[4],k[4][4],lefA[4];double err,A11,A12,A21,A22,B1,B2,B3,B4,C11,C12,C21,C22,D2;g=9.8;h=0.005;for (i=0;i<n;i++){mcar=group[i][0];m1=group[i][1];l1=group[i][2];J1=group[i][3];b=group[i][4];f1=group[i][5];//printf("mcar=%6.3f,m1=%6.3f,l1=%6.3f,J1=%6.3f,b=%6.3,f1=%6.3\n,",mcar,m1, l1,J1,b,f1);err=0;for (int j=0;j<4;j++) //新加的{x[j]=realvalue[0][j];x_temp[j]=realvalue[0][j];}/*for (int j=0;j<4;j++)//修改了{x[j]=Initivalue[j];x_temp[j]=Initivalue[j];}*/for (int q=0;q<N_hit;q++){eks=x[0];eksd=x[1];theta1=x[2];theta1d=x[3];while(fabs(x[2])>(2*Pi)){printf("Error");printf(" q=%d",q);getchar();}A11=mcar+m1;A12=-m1*l1*cos(theta1);A22=m1*l1*l1+J1;A21=A12;C11=b;C12=m1*l1*sin(theta1)*theta1d;C21=0;C22=f1;D2=-m1*g*l1*sin(theta1);B1=eksd;B2=-C11*eksd-C12*theta1d;B3=theta1d;B4=-C22*theta1d-D2;/*%A=[1 0 0 0;% 0 A11 0 A12 ;% 0 0 1 0 ;% 0 A21 0 A22];%lefA = inv(A)*B;%A11x+A12y=B(2)%A21x+A22y=B(4)*/lefA[0]=B1;lefA[1]=(B2*A22-B4*A12)/(A22*A11-A21*A12);lefA[2]=B3;lefA[3]=(B2*A21-B4*A11)/(A12*A21-A22*A11);for (j=0;j<4;j++) //龙格-库塔法{k[j][0]=lefA[0];k[j][1]=lefA[1];k[j][2]=lefA[2];k[j][3]=lefA[3];for (int p=0;p<4;p++){if(j==0) x[p]=x_temp[p]+h/2*k[j][p];if(j==1) x[p]=x_temp[p]+h/2*k[j][p];if(j==2) x[p]=x_temp[p]+h*k[j][p];}}for(j=0;j<4;j++){x[j]=x_temp[j]+(k[0][j]+2*k[1][j]+2*k[2][j]+k[3][j])*h/6;x_temp[j]=x[j];}//getchar();//test uerr=err+pow((x[2]-realvalue[q][2]),2);//err=err+80*pow(x[1],2)+80*pow(x[3],2)+pow(u,2);}//end of for qfit_degree[i]=2+log(2/err)/log(200);///log(2);//9改成200了}}//种群排序void sort(double order_fit[],int index_fit[],int n){int i,j;int t;double temp;for (i=0;i<n;i++)index_fit[i]=i;for (j=1;j<=n-1;j++)for(i=1;i<=n-j;i++){if(order_fit[i]<order_fit[i-1]){temp=order_fit[i];order_fit[i]=order_fit[i-1];order_fit[i-1]=temp;t=index_fit[i];index_fit[i]=index_fit[i-1];index_fit[i-1]=t;}}}//反馈式突变void Feedback_mut(double group[][N_para],double up_limit[],double low_limit[],int index_fit[],double fit_opitimal,int nb){// printf("\nFeedback1 ok\n");double beta;int i,j,best,worse;int n=M;best=index_fit[M-1];for (i=0;i<n*0.9;i++){beta=crandom();worse=index_fit[i];if(nb>50||fit_opitimal<Sigma){if(nb>50) nb=0;for(j=0;j<N_para;j++)group[worse][j]=low_limit[j]+beta*(up_limit[j]-low_limit[j]);}elsefor(j=0;j<N_para;j++){group[worse][j]=(Nu+beta*Vi)*group[best][j];if (group[worse][j]<low_limit[j]||group[worse][j]>up_limit[j])group[worse][j]=group[best][j];}}//printf("\nFeedback 2 ok\n");}//选择操作void Slected(double cross[],double group[][N_para],double fit_degree[],double fit_sum){int j,i=0;double beta,slectvalue[M];beta=crandom();slectvalue[0]=fit_degree[0]/fit_sum;for(i=1;i<M;i++)slectvalue[i]=slectvalue[i-1]+fit_degree[i]/fit_sum;for(i=1;i<M;i++){if(slectvalue[i-1]<beta&&slectvalue[i]>beta)break;}for(j=0;j<N_para;j++)cross[j]=group[i][j];}//计算两个染色体的海明距离int haiming(double crossa[],double crossb[],int n){int num=0;int i;for (i=0;i<n;i++)if(crossa[i]!=crossb[i]) num++;return num;}//交叉操作void Cro_operation(double crossa[],double crossb[],double up_limit[],double low_limit[],int D_hm){int i,j,cro_point,d,zeta=0,sum=0;double cro_temp,beta;double x_temp[N_para];double y_temp[N_para];int rec[6]={0,0,0,0,0,0};if(D_hm==1){for(i=0;i<N_para;i++){if(crossa[i]!=crossb[i])break;}//cro_temp=crossa[i];//crossa[i]=crossb[i];//crossb[i]=cro_tempcro_point=i;}else{//zeta=(int)(crandom(4)+1);for(int ii=0;ii<N_para;ii++){for (int k=0;k<N_para;k++){x_temp[k]=0;y_temp[k]=0;}for(i=0;i<=ii;i++){x_temp[i]=crossa[i];y_temp[i]=crossb[i];}d=haiming(x_temp,y_temp,N_para);if(d>0&&d<D_hm){zeta++;rec[ii]=1;}//break;//>=改成<???}ii=(int)(crandom(zeta)+1);sum=0;for(i=0;sum<ii;i++){sum=sum+rec[i];cro_point=i;;}}//End of elsefor (j=0;j<cro_point;j++){cro_temp=crossa[j];crossa[j]=crossb[j];crossb[j]=cro_temp;}//cro_point--;//改了beta=crandom();cro_temp=(crossa[cro_point]<=crossb[cro_point])?crossa[cro_point]:crossb[cro_point];crossa[cro_point]=cro_temp+beta*fabs(crossa[cro_point]-crossb[cro_point]);beta=crandom();crossb[cro_point]=low_limit[cro_point]+beta*(up_limit[cro_point]-low_limit[cro_poi nt]);}//正交实验产生一个较优染色体void Cro_opiti(double crossa[N_para],double crossb[N_para],double cro_result[N_para],double realvalue[][4])//改了{double matrix[8][6]={//四因素两水平正交试验表1,1,1,1,1,1,1,1,1,2,2,2,1,2,2,1,1,2,1,2,2,2,2,1,2,1,2,1,2,1,2,1,2,2,1,2,2,2,1,1,2,2,2,2,1,2,1,1};int i,j;double fit_temp[8];double kx[N_para]={0,0,0,0,0,0};//changedouble ky[N_para]={0,0,0,0,0,0};//changefor(i=0;i<8;i++)for(j=0;j<N_para;j++){if(matrix[i][j]==1)matrix[i][j]=crossa[j];elsematrix[i][j]=crossb[j];}Fit_calculate(matrix,realvalue,fit_temp,8);for(i=0;i<8;i++)// 改了{for(j=0;j<N_para;j++){if(matrix[i][j]==crossa[j])kx[j]=kx[j]+fit_temp[i];if(matrix[i][j]==crossb[j])ky[j]=ky[j]+fit_temp[i];}}for(j=0;j<N_para;j++){if(kx[j]>ky[j])cro_result[j]=crossa[j];elsecro_result[j]=crossb[j];}}//变异操作void mut_operation(double cro_result[N_para],double up_limit[], double low_limit[]) {int mut_point1,mut_point2;double beta,x1,x2;do{mut_point1=(int)crandom(6);//改了13mut_point2=(int)crandom(6);//改了13}while(mut_point1==mut_point2);x1=(cro_result[mut_point1]-low_limit[mut_point1])/(up_limit[mut_point1]-low_limit [mut_point1]);x2=(cro_result[mut_point2]-low_limit[mut_point2])/(up_limit[mut_point2]-low_limit [mut_point2]);beta=crandom();if(beta<Pm){beta=crandom();cro_result[mut_point1]=(1-beta)*cro_result[mut_point1]+beta*low_limit[mut_point 1]+x2*(up_limit[mut_point1]-cro_result[mut_point1]);cro_result[mut_point2]=(1-beta)*cro_result[mut_point2]+beta*low_limit[mut_point 2]+x1*(up_limit[mut_point2]-cro_result[mut_point2]);}}//产生新一代种群void New_group(double group_temp[][N_para],double group[][N_para],double newfit_degree[],double fit_degree[]){int i,j;int temp;int index[M+Ncross];sort(newfit_degree,index,M+Ncross);for(i=0;i<M;i++){temp=index[Ncross+i];for(j=0;j<N_para;j++){group[i][j]=group_temp[temp][j];}fit_degree[i]=newfit_degree[Ncross+i];}}//种群最优个体,适应度值数据存盘void Data_record(double group[][N_para],double fit_degree[],double fit_population,int index_fit[]){FILE *fp;if((fp=fopen("Result\\Result.txt","a"))==NULL){printf("cannot open the fiel Result.txt\n");exit(0);}int nbest=index_fit[M-1];for(int i=0;i<N_para;i++)fprintf(fp,"%6.5f ",group[nbest][i]);printf("\npara=%6.5f %6.5f %6.5f %6.5f %6.5f %6.5f\n",group[nbest][0],group[n best][1],group[nbest][2],group[nbest][3],group[nbest][4],group[nbest][5]);//家的fprintf(fp,"%6.5f %6.5f\n",fit_degree[M-1],fit_population);fclose(fp);。
#include "stdio.h"#include "stdlib.h"#include "conio.h"#include "math.h"#include "time.h"#define num_C 12 //个体的个数,前6位表示x1,后6位表示x2 #define N 100 //群体规模为100#define pc 0.9 //交叉概率为0.9#define pm 0.1 //变异概率为10%#define ps 0.6 //进行选择时保留的比例#define genmax 2000 //最大代数200int RandomInteger(int low,int high);void Initial_gen(struct unit group[N]);void Sort(struct unit group[N]);void Copy_unit(struct unit *p1,struct unit *p2);void Cross(struct unit *p3,struct unit *p4);void Varation(struct unit group[N],int i);void Evolution(struct unit group[N]);float Calculate_cost(struct unit *p);void Print_optimum(struct unit group[N],int k);/* 定义个体信息*/typedef struct unit{int path[num_C]; //每个个体的信息double cost; //个体代价值};struct unit group[N]; //种群变量groupint num_gen=0; //记录当前达到第几代int main(){int i,j;srand((int)time(NULL)); //初始化随机数发生器Initial_gen(group); //初始化种群Evolution(group); //进化:选择、交叉、变异getch();return 0;}/* 初始化种群*/void Initial_gen(struct unit group[N]){int i,j;struct unit *p;for(i=0;i<=N-1;i++) //初始化种群里的100个个体{p=&group[i]; //p指向种群的第i个个体for(j=0;j<12;j++){p->path[j]=RandomInteger(0,9); //end }Calculate_cost(p); //计算该种群的函数值}//end 初始化种群}/* 种群进化,进化代数由genmax决定*/void Evolution(struct unit group[N]){int i,j;int temp1,temp2,temp3,temp4,temp5;temp1=N*pc/2;temp2=N*(1-pc);temp3=N*(1-pc/2);temp4=N*(1-ps);temp5=N*ps;for(i=1;i<=genmax;i++){//选择for(j=0;j<=temp4-1;j++){ Copy_unit(&group[j],&group[j+temp5]); }//交叉for(j=0;j<=temp1-1;){Cross(&group[temp2+j],&group[temp3+j]);j+=2;}//变异Varation(group,i);}Sort(group);Print_optimum(group,i-1); //输出当代(第i-1代)种群}/* 交叉*/void Cross(struct unit *p3,struct unit *p4){int i,j,cross_point;int son1[num_C],son2[num_C];for(i=0;i<=num_C-1;i++) //初始化son1、son2{son1[i]=-1;son2[i]=-1;}cross_point=RandomInteger(1,num_C-1); //交叉位随机生成//交叉,生成子代//子代1//子代1前半部分直接从父代复制for(i=0;i<=cross_point-1;i++) son1[i]=p3->path[i];for(i=cross_point;i<=num_C-1;i++)for(j=0;j<=num_C-1;j++) //补全p1{son1[i]=p4->path[j];}//end 子代1//子代2//子代1后半部分直接从父代复制for(i=cross_point;i<=num_C-1;i++) son2[i]=p4->path[i];for(i=0;i<=cross_point-1;i++){for(j=0;j<=num_C-1;j++) //补全p1{son2[i]=p3->path[j];}}//end 子代2//end 交叉for(i=0;i<=num_C-1;i++){p3->path[i]=son1[i];p4->path[i]=son2[i];}Calculate_cost(p3); //计算子代p1的函数值Calculate_cost(p4); //计算子代p2的函数值}/* 变异*/void Varation(struct unit group[N],int flag_v){int flag,i,j,k,temp;struct unit *p;flag=RandomInteger(1,100);//在进化后期,增大变异概率if((!flag>(flag_v>100))?(5*100*pm):(100*pm)){i=RandomInteger(0,N-1); //确定发生变异的个体j=RandomInteger(0,num_C-1); //确定发生变异的位k=RandomInteger(0,num_C-1);p=&group[i]; //变异temp=p->path[j];p->path[j]=p->path[k];p->path[k]=temp;Calculate_cost(p); //重新计算变异后的函数值}}/* 将种群中个体按函数值从小到大排序*/void Sort(struct unit group[N]){int i,j;struct unit temp,*p1,*p2;for(j=1;j<=N-1;j++) //排序总共需进行N-1轮{for(i=1;i<=N-1;i++){p1=&group[i-1];p2=&group[i];if(p1->cost>p2->cost) //值大的往后排{Copy_unit(p1,&temp);Copy_unit(p2,p1);Copy_unit(&temp,p2);}}//end 一轮排序}//end 排序}/* 计算某个个体的函数值*/float Calculate_cost(struct unit *p){double x1,x2;x1=0;if(p->path[0]>5){x1=p->path[1]+p->path[2]*0.1+p->path[3]*0.01+p->path[4]*0.001+p->path[5]*0.0001;}else if(p->path[0]<6){x1=0-(p->path[1]+p->path[2]*0.1+p->path[3]*0.01+p->path[4]*0.001+p->path[5]*0.0001);}x2=0;if(p->path[6]>5){}else if(p->path[6]<6){x2=0-(p->path[7]+p->path[8]*0.1+p->path[9]*0.01+p->path[10]*0.001+p->path[11]*0.0001);}p->cost=20+x1*x1+x2*x2-10*(cos(2*3.14*x1)+cos(2*3.14*x2));return(p->cost);}/* 复制种群中的p1到p2中*/void Copy_unit(struct unit *p1,struct unit *p2){int i;for(i=0;i<=num_C-1;i++)p2->path[i]=p1->path[i];p2->cost=p1->cost;}/* 生成一个介于两整型数之间的随机整数*/int RandomInteger(int low,int high){int k;double d;k=rand();k=(k!=RAND_MAX)?k:(k-1); //RAND_MAX是VC中可表示的最大整型数d=(double)k/((double)(RAND_MAX));k=(int)(d*(high-low+1));return (low+k);}/* 输出当代种群中的最优个体*/void Print_optimum(struct unit group[N],int k){struct unit *p;double x1,x2;x1=x2=0;p=&group[0];if(p->path[0]>5){x1=p->path[1]+p->path[2]*0.1+p->path[3]*0.01+p->path[4]*0.001+p->path[5]*0.0001;}else if(p->path[0]<6){}x2=0;if(p->path[6]>5){x2=p->path[7]+p->path[8]*0.1+p->path[9]*0.01+p->path[10]*0.001+p->path[11]*0.0001;}else if(p->path[6]<6){x2=0-(p->path[7]+p->path[8]*0.1+p->path[9]*0.01+p->path[10]*0.001+p->path[11]*0.0001);}printf(" 当x1=%f x2=%f\n",x1,x2);printf(" 函数最小值为:%f \n",p->cost);}。
遗传算法简述及代码详解声明:本文内容整理自网络,认为原作者同意转载,如有冒犯请联系我。
遗传算法基本内容遗传算法为群体优化算法,也就是从多个初始解开始进行优化,每个解称为一个染色体,各染色体之间通过竞争、合作、单独变异,不断进化。
遗传学与遗传算法中的基础术语比较染色体:又可以叫做基因型个体(individuals)群体/种群(population):一定数量的个体组成,及一定数量的染色体组成,群体中个体的数量叫做群体大小。
初始群体:若干染色体的集合,即解的规模,如30,50等,认为是随机选取的数据集合。
适应度(fitness):各个个体对环境的适应程度优化时先要将实际问题转换到遗传空间,就是把实际问题的解用染色体表示,称为编码,反过程为解码/译码,因为优化后要进行评价(此时得到的解是否较之前解优越),所以要返回问题空间,故要进行解码。
SGA采用二进制编码,染色体就是二进制位串,每一位可称为一个基因;如果直接生成二进制初始种群,则不必有编码过程,但要求解码时将染色体解码到问题可行域内。
遗传算法的准备工作:1) 数据转换操作,包括表现型到基因型的转换和基因型到表现型的转换。
前者是把求解空间中的参数转化成遗传空间中的染色体或者个体(encoding),后者是它的逆操作(decoding)2) 确定适应度计算函数,可以将个体值经过该函数转换为该个体的适应度,该适应度的高低要能充分反映该个体对于解得优秀程度。
非常重要的过程。
遗传算法基本过程为:1) 编码,创建初始群体2) 群体中个体适应度计算3) 评估适应度4) 根据适应度选择个体5) 被选择个体进行交叉繁殖6) 在繁殖的过程中引入变异机制7) 繁殖出新的群体,回到第二步实例一:(建议先看实例二)求 []30,0∈x 范围内的()210-=x y 的最小值1) 编码算法选择为"将x 转化为2进制的串",串的长度为5位(串的长度根据解的精度设 定,串长度越长解得精度越高)。
C语言遗传算法代码以下为遗传算法的源代码,计算一元代函数的代码和二元函数的代码以+++++++++++++++++++++++++++++++++++++为分割线分割开来,请自行选择适合的代码,使用时请略看完代码的注释,在需要更改的地方更改为自己需要的代码。
+++++++++++++++++++++++++++++++一元函数代码++++++++++++++++++++++++++++#include <stdio.h>#include<stdlib.h>#include<time.h>#include<math.h>#define POPSIZE 1000#define maximization 1#define minimization 2#define cmax 100#define cmin 0#define length1 20#define chromlength length1 //染色体长度//注意,你是求最大值还是求最小值int functionmode=minimization;//变量的上下限的修改开始float min_x1=-2;//变量的下界float max_x1=-1;//变量的上界//变量的上下限的修改结束int popsize; //种群大小int maxgeneration; //最大世代数double pc; //交叉率double pm; //变异率struct individual{char chrom[chromlength+1];double value;double fitness; //适应度};int generation; //世代数int best_index;int worst_index;struct individual bestindividual; //最佳个体struct individual worstindividual; //最差个体struct individual currentbest;struct individual population[POPSIZE];//函数声明void generateinitialpopulation();void generatenextpopulation();void evaluatepopulation();long decodechromosome(char *,int,int);void calculateobjectvalue();void calculatefitnessvalue();void findbestandworstindividual();void performevolution();void selectoperator();void crossoveroperator();void mutationoperator();void input();void outputtextreport();void generateinitialpopulation( ) //种群初始化{int i,j;for (i=0;i<popsize; i++){for(j=0;j<chromlength;j++){population[i].chrom[j]=(rand()%20<10)?'0':'1';}population[i].chrom[chromlength]='\0';}}void generatenextpopulation() //生成下一代{selectoperator();crossoveroperator();mutationoperator();}void evaluatepopulation() //评价个体,求最佳个体{calculateobjectvalue();calculatefitnessvalue();findbestandworstindividual();}long decodechromosome(char *string ,int point,int length) //给染色体解码{int i;long decimal=0;char*pointer;for(i=0,pointer=string+point;i<length;i++,pointer++)if(*pointer-'0'){decimal +=(long)pow(2,i);}return (decimal);}void calculateobjectvalue() //计算函数值{int i;long temp1,temp2;double x1;for (i=0; i<popsize; i++){temp1=decodechromosome(population[i].chrom,0,length1);x1=(max_x1-min_x1)*temp1/(1024*1024-1)+min_x1;//目标函数修改开始population[i].value=(pow(x1,5)-3*x1-1)*(pow(x1,5)-3*x1-1);//目标函数修改结束}}void calculatefitnessvalue()//计算适应度{int i;double temp;for(i=0;i<popsize;i++){if(functionmode==maximization){if((population[i].value+cmin)>0.0){temp=cmin+population[i].value;}else{temp=0.0;}}else if (functionmode==minimization){if(population[i].value<cmax){temp=cmax-population[i].value;}else{ temp=0.0;}}population[i].fitness=temp;}}void findbestandworstindividual( ) //求最佳个体和最差个体{int i;double sum=0.0;bestindividual=population[0];worstindividual=population[0];for (i=1;i<popsize; i++){if (population[i].fitness>bestindividual.fitness){bestindividual=population[i];best_index=i;}else if (population[i].fitness<worstindividual.fitness) {worstindividual=population[i];worst_index=i;}sum+=population[i].fitness;}if (generation==0){currentbest=bestindividual;}else{if(bestindividual.fitness>=currentbest.fitness){currentbest=bestindividual;}}}void performevolution() //演示评价结果{if (bestindividual.fitness>currentbest.fitness){ currentbest=population[best_index];}else{population[worst_index]=currentbest;}}void selectoperator() //比例选择算法{int i,index;double p,sum=0.0;double cfitness[POPSIZE];struct individual newpopulation[POPSIZE];for(i=0;i<popsize;i++){sum+=population[i].fitness;}for(i=0;i<popsize; i++){cfitness[i]=population[i].fitness/sum;}for(i=1;i<popsize; i++){cfitness[i]=cfitness[i-1]+cfitness[i];}for (i=0;i<popsize;i++){p=rand()%1000/1000.0;index=0;while (p>cfitness[index]){index++;}newpopulation[i]=population[index];}for(i=0;i<popsize; i++){population[i]=newpopulation[i];}}void crossoveroperator() //交叉算法{int i,j;int index[POPSIZE];int point,temp;double p;char ch;for (i=0;i<popsize;i++){index[i]=i;}for (i=0;i<popsize;i++){point=rand()%(popsize-i);temp=index[i];index[i]=index[point+i];index[point+i]=temp;}for (i=0;i<popsize-1;i+=2){p=rand()%1000/1000.0;if (p<pc){point=rand()%(chromlength-1)+1;for (j=point; j<chromlength;j++){ch=population[index[i]].chrom[j];population[index[i]].chrom[j]=population[index[i+1]].chrom[j];population[index[i+1]].chrom[j]=ch;}}}}void mutationoperator() //变异操作{int i,j;double p;for (i=0;i<popsize;i++){for(j=0;j<chromlength;j++){p=rand()%1000/1000.0;if (p<pm){population[i].chrom[j]=(population[i].chrom[j]=='0')?'1':'0';}}}void input() //数据输入{ //printf("初始化全局变量:\n");//printf(" 种群大小(50-500):");//scanf("%d", &popsize);popsize=500;if((popsize%2) != 0){//printf( " 种群大小已设置为偶数\n");popsize++;};//printf(" 最大世代数(100-300):");//scanf("%d", &maxgeneration);maxgeneration=200;//printf(" 交叉率(0.2-0.99):");//scanf("%f", &pc);pc=0.95;//printf(" 变异率(0.001-0.1):");//scanf("%f", &pm);pm=0.03;}void outputtextreport()//数据输出{int i;double sum;double average;sum=0.0;for(i=0;i<popsize;i++){sum+=population[i].value;}average=sum/popsize;printf("当前世代=%d\n当前世代平均函数值=%f\n当前世代最优函数值=%f\n",generation,average,population[best_index].value);}void main() //主函数{ int i;long temp1,temp2;double x1,x2;generation=0;input();generateinitialpopulation();evaluatepopulation();while(generation<maxgeneration)generation++;generatenextpopulation();evaluatepopulation();performevolution();outputtextreport();}printf("\n");printf(" 统计结果: ");printf("\n");//printf("最大函数值等于:%f\n",currentbest.fitness);printf("其染色体编码为:");for (i=0;i<chromlength;i++){printf("%c",currentbest.chrom[i]);}printf("\n");temp1=decodechromosome(currentbest.chrom,0,length1);x1=(max_x1-min_x1)*temp1/(1024*1024-1)+min_x1;printf("x1=%lf\n",x1);//这是需要修改的地方printf("最优值等于:%f\n",(pow(x1,5)-3*x1-1)*(pow(x1,5)-3*x1-1));}+++++++++++++++++++++++++二元函数代码+++++++++++++++++++++++++++++++++++++++++ #include <stdio.h>#include<stdlib.h>#include<time.h>#include<math.h>#define POPSIZE 500#define maximization 1#define minimization 2#define cmax 100#define cmin 0#define length1 20#define length2 20#define chromlength length1+length2 //染色体长度//-----------求最大还是最小值int functionmode=maximization;//-----------//-----------变量上下界float min_x1=0;float max_x1=3;float min_x2=1;float max_x2=5;//-----------int popsize; //种群大小int maxgeneration; //最大世代数double pc; //交叉率double pm; //变异率struct individual{char chrom[chromlength+1];double value;double fitness; //适应度};int generation; //世代数int best_index;int worst_index;struct individual bestindividual; //最佳个体struct individual worstindividual; //最差个体struct individual currentbest;struct individual population[POPSIZE];//函数声明void generateinitialpopulation();void generatenextpopulation();void evaluatepopulation();long decodechromosome(char *,int,int);void calculateobjectvalue();void calculatefitnessvalue();void findbestandworstindividual();void performevolution();void selectoperator();void crossoveroperator();void mutationoperator();void input();void outputtextreport();void generateinitialpopulation( ) //种群初始化{int i,j;for (i=0;i<popsize; i++){for(j=0;j<chromlength;j++){population[i].chrom[j]=(rand()%40<20)?'0':'1';}population[i].chrom[chromlength]='\0';}}void generatenextpopulation() //生成下一代{selectoperator();crossoveroperator();mutationoperator();}void evaluatepopulation() //评价个体,求最佳个体{calculateobjectvalue();calculatefitnessvalue();findbestandworstindividual();}long decodechromosome(char *string ,int point,int length) //给染色体解码{int i;long decimal=0;char*pointer;for(i=0,pointer=string+point;i<length;i++,pointer++)if(*pointer-'0'){decimal +=(long)pow(2,i);}return (decimal);}void calculateobjectvalue() //计算函数值{int i;long temp1,temp2;double x1,x2;for (i=0; i<popsize; i++){temp1=decodechromosome(population[i].chrom,0,length1);temp2=decodechromosome(population[i].chrom,length1,length2);x1=(max_x1-min_x1)*temp1/(1024*1024-1)+min_x1;x2=(max_x2-min_x2)*temp2/(1024*1024-1)+min_x2;//-----------函数population[i].value=x1*x1+sin(x1*x2)-x2*x2;//-----------}}void calculatefitnessvalue()//计算适应度{int i;double temp;for(i=0;i<popsize;i++){if(functionmode==maximization){if((population[i].value+cmin)>0.0){temp=cmin+population[i].value;}else{temp=0.0;}}else if (functionmode==minimization){if(population[i].value<cmax){temp=cmax-population[i].value;}else{ temp=0.0;}}population[i].fitness=temp;}}void findbestandworstindividual( ) //求最佳个体和最差个体{int i;double sum=0.0;bestindividual=population[0];worstindividual=population[0];for (i=1;i<popsize; i++){if (population[i].fitness>bestindividual.fitness){bestindividual=population[i];best_index=i;}else if (population[i].fitness<worstindividual.fitness) {worstindividual=population[i];worst_index=i;}sum+=population[i].fitness;}if (generation==0){currentbest=bestindividual;}else{if(bestindividual.fitness>=currentbest.fitness){currentbest=bestindividual;}}}void performevolution() //演示评价结果{if (bestindividual.fitness>currentbest.fitness){currentbest=population[best_index];}else{population[worst_index]=currentbest;}}void selectoperator() //比例选择算法{int i,index;double p,sum=0.0;double cfitness[POPSIZE];struct individual newpopulation[POPSIZE];for(i=0;i<popsize;i++){sum+=population[i].fitness;}for(i=0;i<popsize; i++){cfitness[i]=population[i].fitness/sum;}for(i=1;i<popsize; i++){cfitness[i]=cfitness[i-1]+cfitness[i];}for (i=0;i<popsize;i++){p=rand()%1000/1000.0;index=0;while (p>cfitness[index]){index++;}newpopulation[i]=population[index];}for(i=0;i<popsize; i++){population[i]=newpopulation[i];}}void crossoveroperator() //交叉算法{int i,j;int index[POPSIZE];int point,temp;double p;char ch;for (i=0;i<popsize;i++){index[i]=i;}for (i=0;i<popsize;i++){point=rand()%(popsize-i);temp=index[i];index[i]=index[point+i];index[point+i]=temp;}for (i=0;i<popsize-1;i+=2){p=rand()%1000/1000.0;if (p<pc){point=rand()%(chromlength-1)+1;for (j=point; j<chromlength;j++){ch=population[index[i]].chrom[j];population[index[i]].chrom[j]=population[index[i+1]].chrom[j];population[index[i+1]].chrom[j]=ch;}}}}void mutationoperator() //变异操作{int i,j;double p;for (i=0;i<popsize;i++){for(j=0;j<chromlength;j++){p=rand()%1000/1000.0;if (p<pm){population[i].chrom[j]=(population[i].chrom[j]=='0')?'1':'0';}}}}void input() //数据输入{ //printf("初始化全局变量:\n");//printf(" 种群大小(50-500):");//scanf("%d", &popsize);popsize=200;if((popsize%2) != 0){//printf( " 种群大小已设置为偶数\n");popsize++;};//printf(" 最大世代数(100-300):");//scanf("%d", &maxgeneration);maxgeneration=200;//printf(" 交叉率(0.2-0.99):");//scanf("%f", &pc);pc=0.9;//printf(" 变异率(0.001-0.1):");//scanf("%f", &pm);pm=0.003;}void outputtextreport()//数据输出{int i;double sum;double average;sum=0.0;for(i=0;i<popsize;i++){sum+=population[i].value;}average=sum/popsize;printf("当前世代=%d\n当前世代平均函数值=%f\n当前世代最优函数值=%f\n",generation,average,population[best_index].value);}void main() //主函数{ int i;long temp1,temp2;double x1,x2;generation=0;input();generateinitialpopulation();evaluatepopulation();while(generation<maxgeneration){generation++;generatenextpopulation();evaluatepopulation();performevolution();outputtextreport();}printf("\n");printf(" 统计结果: ");printf("\n");//printf("最大函数值等于:%f\n",currentbest.fitness);printf("其染色体编码为:");for (i=0;i<chromlength;i++){printf("%c",currentbest.chrom[i]);}printf("\n");temp1=decodechromosome(currentbest.chrom,0,length1);temp2=decodechromosome(currentbest.chrom,length1,length2);x1=(max_x1-min_x1)*temp1/(1024*1024-1)+min_x1;x2=(max_x2-min_x2)*temp2/(1024*1024-1)+min_x2;printf("x=%lf,y=%lf\n",x1,x2);//-----------修改函数printf("最大值=%f\n",x1*x1+sin(x1*x2)-x2*x2);//-----------}。
C++实现简单遗传算法本⽂实例讲述了C++实现简单遗传算法。
分享给⼤家供⼤家参考。
具体实现⽅法如下://遗传算法 GA#include<iostream>#include <cstdlib>#include<bitset>using namespace std;const int L=5; //定义编码的长度int f(int x) //定义测设函数f(x){int result;result=x*x*x-60*x*x+900*x+100;return result;}int main(int argc,char *argv[]){int a(0),b(32); //定义x的定义域范围const int pop_size=8; //定义种群⼤⼩// int L; //指定编码的长度const int NG=20; //指定种群最⼤的繁殖的代数int t=0; //当前繁殖的代数int p[pop_size]; //定义种群int q[pop_size]; //定义繁殖种群即种群的下⼀代srand(6553); //定义随机数⽣成的种⼦double sum; //适值总和double avl_sum; //适度平均值double p_probability[pop_size]; //适值概率double pp[pop_size];double pro; //定义随机⽣成的概率float pc=0.90; //定义交叉的概率float pm=0.05; //定义变异的概率cout<<"初始的种群 ";for(int i=0;i<pop_size;i++) //⽣成初始的第0代种群{p[i]=rand()%31;cout<<p[i]<<" ";}cout<<endl;cout<<endl;void Xover(int &,int &); //声明交叉函数//当停⽌准则不满⾜即繁殖代数没到最⼤代数 ,继续繁殖while(t<=NG){cout<<"繁殖的代数:t="<<t<<endl;sum=0.0;for(int i=0;i<pop_size;i++){q[i]=p[i];cout<<q[i]<<" ";}cout<<endl;for(int i=0;i<pop_size;i++) //计算sumsum +=f(p[i]);avl_sum=sum/pop_size;cout<<"sum="<<sum<<endl;cout<<"适度平均值="<<avl_sum<<endl;for(int i=0;i<pop_size;i++) //计算适值概率{p_probability[i]=f(p[i])/sum;if(i==0){pp[i]=p_probability[i];cout<<"pp"<<i<<"="<<pp[i]<<endl;}else{pp[i]=p_probability[i]+pp[i-1];cout<<"pp"<<i<<"="<<pp[i]<<endl;}//cout<<"p_probability"<<i<<"="<<p_probability[i]<<endl;}//选择双亲for(int i=0;i<pop_size;i++)pro=rand()%1000/1000.0;if(pro>=pp[0]&&pro<pp[1])p[i]=q[0];else if(pro>=pp[1]&&pro<pp[2])p[i]=q[1];else if(pro>=pp[2]&&pro<pp[3])p[i]=q[2];else if(pro>=pp[3]&&pro<pp[4])p[i]=q[3];else if(pro>=pp[4]&&pro<pp[5])p[i]=q[4];elsep[i]=q[5];}//杂交算⼦int r=0;int z=0;for(int j=0;j<pop_size;j++){pro=rand()%1000/1000.0;if(pro<pc){++z;if(z%2==0)Xover(p[r],p[j]);elser=j;}}//变异算⼦for(int i=1;i<=pop_size;i++)for(int j=0;j<L;j++){pro=rand()%1000/1000.0; //在【0,1】区间产⽣随机数if(pro<pm){bitset<L>v(p[i]);v.flip(j);p[i]=v.to_ulong();}}t++;cout<<endl; //种群繁殖⼀代}cout<<"最终结果:";for(int i(0);i<pop_size;i++) //算法结束,输出结果{cout<<p[i]<<" ";}cout<<endl;return 0;}//定义杂交操作void Xover(int &a,int &b){int pos; //随机⽣成杂交点即第⼏个分量进⾏相互交换pos=rand()%5+1; //在n个分量中,随机确定第pos个分量int j,k;j=pos;k=pos;bitset<L>e(a);bitset<L>f(b); //前pos个分量进⾏相互交换bitset<L>g;bitset<L>h;for(int i=0;i<pos;i++){if(e[i]==1)g.set(i);}for(int i=0;i<pos;i++){if(f[i]==1)h.set(i);}for(j;j<L;j++)if(f[j]==1)g.set(j);}for(k;k<L;k++){if(e[k]==1)h.set(k);}a=g.to_ulong();b=h.to_ulong();}希望本⽂所述对⼤家的C++程序设计有所帮助。
以下是一个简单的遗传算法的C语言代码示例:c#include <stdio.h>#include <stdlib.h>#include <time.h>#include <math.h>#define POPULATION_SIZE 100#define GENE_LENGTH 10#define MAX_GENERATIONS 1000#define MUTATION_RATE 0.01#define CROSSOVER_RATE 0.8typedef struct Individual {char genes[GENE_LENGTH];double fitness;} Individual;double calculate_fitness(Individual* individual) {// 计算适应度函数,这里使用简单的二进制字符串中1的个数作为适应度 int count = 0;for (int i = 0; i < GENE_LENGTH; i++) {if (individual->genes[i] == '1') {count++;}}return count;}void initialize_population(Individual* population) {// 初始化种群for (int i = 0; i < POPULATION_SIZE; i++) {for (int j = 0; j < GENE_LENGTH; j++) {population[i].genes[j] = rand() % 2 ? '0' : '1';}population[i].fitness = calculate_fitness(&population[i]); }}void selection(Individual* population, Individual* parents) {// 选择操作,采用轮盘赌算法选择两个父代个体double total_fitness = 0;for (int i = 0; i < POPULATION_SIZE; i++) {total_fitness += population[i].fitness;}double rand1 = rand() / (double)RAND_MAX * total_fitness;double rand2 = rand() / (double)RAND_MAX * total_fitness;double cumulative_fitness = 0;int parent1_index = -1, parent2_index = -1;for (int i = 0; i < POPULATION_SIZE; i++) {cumulative_fitness += population[i].fitness;if (rand1 < cumulative_fitness && parent1_index == -1) {parent1_index = i;}if (rand2 < cumulative_fitness && parent2_index == -1) {parent2_index = i;}}parents[0] = population[parent1_index];parents[1] = population[parent2_index];}void crossover(Individual* parents, Individual* offspring) {// 交叉操作,采用单点交叉算法生成两个子代个体int crossover_point = rand() % GENE_LENGTH;for (int i = 0; i < crossover_point; i++) {offspring[0].genes[i] = parents[0].genes[i];offspring[1].genes[i] = parents[1].genes[i];}for (int i = crossover_point; i < GENE_LENGTH; i++) {offspring[0].genes[i] = parents[1].genes[i];offspring[1].genes[i] = parents[0].genes[i];}offspring[0].fitness = calculate_fitness(&offspring[0]);offspring[1].fitness = calculate_fitness(&offspring[1]);}void mutation(Individual* individual) {// 变异操作,以一定概率翻转基因位上的值for (int i = 0; i < GENE_LENGTH; i++) {if (rand() / (double)RAND_MAX < MUTATION_RATE) {individual->genes[i] = individual->genes[i] == '0' ? '1' : '0'; }}individual->fitness = calculate_fitness(individual);}void replace(Individual* population, Individual* offspring) {// 替换操作,将两个子代个体中适应度更高的一个替换掉种群中适应度最低的一个个体int worst_index = -1;double worst_fitness = INFINITY;for (int i = 0; i < POPULATION_SIZE; i++) {if (population[i].fitness < worst_fitness) {worst_index = i;worst_fitness = population[i].fitness;}}if (offspring[0].fitness > worst_fitness || offspring[1].fitness > worst_fitness) {if (offspring[0].fitness > offspring[1].fitness) {population[worst_index] = offspring[0];} else {population[worst_index] = offspring[1];}}}。
此例程总共包含3个文件:main.c(主函数);GA.c(包含3个所用函数);GA.h(头文件),3个文件截图如下:用visual c++或者visual stutio创建工程,然后将上述3个文件包含进工程,编译运行即可。
亲测可行!!!3个文件代码分别如下:1、main.c:#include<iostream>#include"GA.h"using namespace std;/*******************************************************************GA demo求函数y=x*sin(10*pai*x)+2.0的最大值编码:浮点数,1位初始群体数:50变异概率:0.8进化代数:100取值范围:[0,4]变异步长:0.004注:因为是单数浮点数编码,所以未使用基因重组函数**********************************************************************/int main(){GenEngine genEngine(50,0.8,0.8,1,100,0,4);genEngine.OnStartGenAlg();getchar();}2、GA.c:#include<vector>#include<stdio.h>#include <stdlib.h>#include <time.h>#include<iostream>#include"GA.h"using namespace std;//srand((unsigned) time(NULL));double random(){double randNum;randNum=rand()*1.0/RAND_MAX;return randNum;}GenAlg::GenAlg(){}void GenAlg::init(int popsize, double MutRate, double CrossRate, int GenLenght,double LeftPoint,double RightPoint){popSize = popsize;mutationRate = MutRate;crossoverRate = CrossRate;chromoLength = GenLenght;totalFitness = 0;generation = 0;//fittestGenome = 0;bestFitness = 0.0;worstFitness = 99999999;averageFitness = 0;maxPerturbation=0.004;leftPoint=LeftPoint;rightPoint=RightPoint;//清空种群容器,以初始化vecPop.clear();for (int i=0; i<popSize; i++){//类的构造函数已经把适应性评分初始化为0vecPop.push_back(Genome());//把所有的基因编码初始化为函数区间内的随机数。
%%GA求有约束下函数最小值,可求一般线性规划和非线性规划模型%%以下是主程序,完整代码可加qq七七零一二四零四久clcclear all;close all;%warning off%% 参数初始化popsize=100;%种群规模lenchrom=3;%染色体长度pc=0.7;%交叉概率pm=0.3;%变异概率maxgen=100;%最大迭代代数popmax=50;popmin=0;bound=[popmin popmax;popmin popmax;popmin popmax];%变量范围%%生成初始解for i=1:popsizeGApop(i,:)=Code(lenchrom,bound);%产生初始种群fitness(i)=fun(GApop(i,:));%计算适应度end[bestfitness bestindex]=min(fitness);zbest=GApop(bestindex,:);gbest=GApop;fitnessgbest=fitness;fitnesszbest=bestfitness;%%迭代寻优for i=1:maxgenGApop=Select(GApop,fitness,popsize);GApop=Cross(pc,lenchrom,GApop,popsize,bound);%交叉操作GApop=Mutation(pm,lenchrom,GApop,popsize,[i,maxgen],bound);%变异操作 pop=GApop;for j=1:popsizeif 1.0*pop(j,1)-1.0*pop(j,2)+1.0*pop(j,3)<=20if 3*pop(j,1)+2*pop(j,2)+4*pop(j,3)<=42if 3*pop(j,1)+2*pop(j,2)<=30fitness(j)=fun(pop(j,:));%适应度值endendendif fitness(j)<fitnessgbest%个体最优更新gbest(j,:)=pop(j,:);fitnessgbest=fitness(j);endif fitness(j)<fitnesszbest%种群最优更新zbest=pop(j,:);fitnesszbest=fitness(j);endendyy(i)=fitnesszbest;end%% 结果disp '***************best particle number******************'zbest%%plot(yy,'linewidth',2);title(['适应度曲线' '终止代数=' num2str(maxgen)]); xlabel('进化代数');ylabel('适应度');grid on%%输出结果子程序如下。
function [result,individual]=GA_OPT(popsize,stringlength,pc,pm,fun,a,b)%popsize初始种群数量%stringlength染色体长度%fun需要优化的函数%a,b是区间上下界%pc交叉概率0.9%pm变异概率0.08popsize=200;fun=@(x)x.* sin(10*pi*x)+2.0;stringlength=22;pc=0.9;pm=0.08;a=-1;b=2;pop=initial(popsize,stringlength,fun,a,b);%产生初始种群for i=1:200[bestindividual,bestvalue]=best(pop,stringlength);%计算个体适应度值newpop=selection(pop,popsize,stringlength);%比例选择运算newpop=crossover(newpop,stringlength,fun,a,b,pc);%单点交叉运算newpop=mutation(newpop,stringlength,fun,a,b,pm);%基本位变异运算pop=newpop;%产生新一代种群end[bestindividual,bestvalue]=best(pop,stringlength);result=bestvalue;individual=bestindividual;%得到最优函数值%--------种群初始化,随机生成二进制与解码-------------%function pop=initial(popsize,stringlength,fun,a,b)pop=round(rand(popsize,stringlength+2));%随机生成二进制数for i=1:popsize %在种群内pop(i,stringlength+1)=sum(2.^(stringlength-1:-1:0).*pop(i,1:stringlength))*(b-a)/(2^stringlength-1)+a; %把二进制数转化为对应的十进制数pop(i,stringlength+2)=fun(pop(i,stringlength+1));%求出二进制转化为十进制数后对应的函数值,为下面的计算个体适应值做准备%生成的pop矩阵为popsize*(stringlength+2)的矩阵,前面的stringlength列位二进制数%第stringlength+1列为二进制数转化为对应的十进制数,第stringlength+2列为二进制对应的函数值end%------------选择算子,按转轮赌方式方式选择-------------%function newpop=selection(pop,popsize,stringlength)totalfit=sum(pop(:,stringlength+2));%求种群中所有适应度函数之和prob=pop(:,stringlength+2)/totalfit;%计算每个个体占种群之和的比例prob=cumsum(prob);%计算比例的累积总和newin=1;while newin<=popsize %转轮赌方式生成新的个体rns=rand; %模拟赌盘操作,随机产生一个概率i=find(prob>rns);%找出个体的概率满足转轮赌方式的个体,即找出可以遗传到下一代的个体i=i(1);newpop(newin,:)=pop(i, :);%生成新的种群newin=newin+1;%继续循环end%----------------交叉算子,实现交叉运算-------------------%function newpop=crossover(newpop,stringlength,fun,a,b,pc)[px,py]=size(newpop);%求出新种群矩阵的大小(行和列)for i=1:2:px-1if rand<=pc%如果产生的随机数小于交叉概率,则进行交叉cpoint=unidrnd(stringlength-1);%随机生成一个1到stringlength-1的数,作为交叉点newpop(i,1:stringlength)=[newpop(i,1:cpoint),newpop(i+1,(cpoint+1):stringlength)];newpop(i+1,1:stringlength)=[newpop(i+1,1:cpoint),newpop(i,(cpoint+1):stringlength)];%在交叉点处实现第i与i+1二进制数的交叉newpop(i,stringlength+1)=sum(2.^(stringlength-1:-1:0).*newpop(i,1:stringlength))*(b-a)/(2^stringlen gth-1)+a;newpop(i+1,stringlength+1)=sum(2.^(stringlength-1:-1:0).*newpop(i+1,1:stringlength))*(b-a)/(2^stri nglength-1)+a;%算出交叉后的二进制数对应的十进制数newpop(i,stringlength+2)=fun(newpop(i,stringlength+1));newpop(i+1,stringlength+1)=fun(newpop(i+1,stringlength+1));%算出交叉后的二进制数对应的函数值elsenewpop(i, :)=newpop(i, :);newpop(i+1, :)=newpop(i+1, :);%形成新的种群矩阵endend%-----------------变异算子,实现变异运算-------------------%function newpop=mutation(newpop,stringlength,fun,a,b,pm)[px,py]=size(newpop);%求出新种群矩阵的大小(行和列)for i=1:pxif(rand<=pm)%随机生成一个概率小于变异概率后,实现变异运算mpoint=unidrnd(stringlength);%随机生成一个1到stringlength的数,作为变异点newpop(i,mpoint)=abs(newpop(i,mpoint)-1);%在变异点实现变异,使0变为1,1变为0 newpop(i,stringlength+1)=sum(2.^(stringlength-1:-1:0).*newpop(i,1:stringlength))*(b-a)/(2^stringlen gth-1)+a;%算出变异后的二进制数对应的十进制数newpop(i,stringlength+2)=fun(newpop(i,stringlength+1));%算出变异后的二进制数对应的函数值elsenewpop(i, :)=newpop(i, :);%形成新的种群矩阵endend%----------------求最大适应值-----------------%function [bestindividual,bestfit]=best(pop,stringlength)[px,py]=size(pop);%求出新种群矩阵的大小(行和列)bestindividual=pop(1,stringlength+1);bestfit=pop(1,stringlength+2);%把种群的第一个数作为初始值for i=2:px%在种群中从第二项开始if bestfit<pop(i,stringlength+2)%种群中如果哪一项比哪一项大,则代替之bestfit=pop(i,stringlength+2);bestindividual=pop(i,stringlength+1);%选出种群中最大的适应值,自变量的值和函数值endend。
遗传算法C语言代码遗传算法C语言代码遗传算法C语言代码// GA.cpp : Defines the entry point for the console application.///*这是一个非常简单的遗传算法源代码,是由Denis Cormier (North Carolina State University)开发的,Sita S.Raghavan (University of North Carolina at Charlotte)修正。
代码保证尽可能少,实际上也不必查错。
对一特定的应用修正此代码,用户只需改变常数的定义并且定义“评价函数”即可。
注意代码的设计是求最大值,其中的目标函数只能取正值;且函数值和个体的适应值之间没有区别。
该系统使用比率选择、精华模型、单点杂交和均匀变异。
如果用 Gaussian变异替换均匀变异,可能得到更好的效果。
代码没有任何图形,甚至也没有屏幕输出,主要是保证在平台之间的高可移植性。
读者可以从, 目录 coe/evol中的文件prog.c中获得。
要求输入的文件应该命名为‘gadata.txt’;系统产生的输出文件为‘galog.txt’。
输入的文件由几行组成:数目对应于变量数。
且每一行提供次序——对应于变量的上下界。
如第一行为第一个变量提供上下界,第二行为第二个变量提供上下界,等等。
*/#include <stdio.h>#include <stdlib.h>#include <math.h>/* Change any of these parameters to match your needs *///请根据你的需要来修改以下参数#define POPSIZE 50 /* population size 种群大小*/#define MAXGENS 1000 /* max. number of generations 最大基因个数*/const int NVARS = 3; /* no. of problem variables 问题变量的个数*/#define PXOVER 0.8 /* probability of crossover 杂交概率*/#define PMUTATION 0.15 /* probability of mutation 变异概率*/#define TRUE 1#define FALSE 0int generation; /* current generation no. 当前基因个数*/int cur_best; /* best individual 最优个体*/FILE *galog; /* an output file 输出文件指针*/struct genotype /* genotype (GT), a member of the population 种群的一个基因的结构体类型*/{double gene[NVARS]; /* a string of variables 变量*/double fitness; /* GT's fitness 基因的适应度*/double upper[NVARS]; /* GT's variables upper bound 基因变量的上界*/double lower[NVARS]; /* GT's variables lower bound 基因变量的下界*/double rfitness; /* relative fitness 比较适应度*/double cfitness; /* cumulative fitness 积累适应度*/};struct genotype population[POPSIZE+1]; /* population 种群*/struct genotype newpopulation[POPSIZE+1]; /* new population; 新种群*//* replaces the old generation *///取代旧的基因/* Declaration of procedures used by this genetic algorithm *///以下是一些函数声明void initialize(void);double randval(double, double);void evaluate(void);void keep_the_best(void);void elitist(void);void select(void);void crossover(void);void Xover(int,int);void swap(double *, double *);void mutate(void);void report(void);/**************************************** ***********************//* Initialization function: Initializes the values of genes *//* within the variables bounds. It also initializes (to zero) *//* all fitness values for each member of the population. It *//* reads upper and lower bounds of each variable from the *//* input file `gadata.txt'. It randomlygenerates values *//* between these bounds for each gene of each genotype in the *//* population. The format of the input file `gadata.txt' is *//* var1_lower_bound var1_upper bound */ /* var2_lower_bound var2_upper bound ... */ /**************************************** ***********************/void initialize(void){FILE *infile;int i, j;double lbound, ubound;if ((infile = fopen("gadata.txt","r"))==NULL){fprintf(galog,"\nCannot open input file!\n");exit(1);}/* initialize variables within the bounds *///把输入文件的变量界限输入到基因结构体中for (i = 0; i < NVARS; i++){fscanf(infile, "%lf",&lbound);fscanf(infile, "%lf",&ubound);for (j = 0; j < POPSIZE; j++){population[j].fitness = 0;population[j].rfitness = 0;population[j].cfitness = 0;population[j].lower[i] = lbound;population[j].upper[i]= ubound;population[j].gene[i] = randval(population[j].lower[i],population[j].upper[i]);}}fclose(infile);}/**************************************** *******************//* Random value generator: Generates a value within bounds *//**************************************** *******************///随机数产生函数double randval(double low, double high) {double val;val = ((double)(rand()%1000)/1000.0)*(high - low) + low;return(val);}/*************************************************************//* Evaluation function: This takes a user defined function. *//* Each time this is changed, the code has to be recompiled. *//* The current function is: x[1]^2-x[1]*x[2]+x[3] *//**************************************** *********************///评价函数,可以由用户自定义,该函数取得每个基因的适应度void evaluate(void){int mem;int i;double x[NVARS+1];for (mem = 0; mem < POPSIZE; mem++){for (i = 0; i < NVARS; i++)x[i+1] = population[mem].gene[i];population[mem].fitness = (x[1]*x[1]) - (x[1]*x[2]) + x[3];}}/**************************************** ***********************//* Keep_the_best function: This function keeps track of the *//* best member of the population. Note that the last entry in *//* the array Population holds a copy of the best individual *//**************************************** ***********************///保存每次遗传后的最佳基因void keep_the_best(){int mem;int i;cur_best = 0;/* stores the index of the best individual*///保存最佳个体的索引for (mem = 0; mem < POPSIZE; mem++){if (population[mem].fitness > population[POPSIZE].fitness){cur_best = mem;population[POPSIZE].fitness = population[mem].fitness;}}/* once the best member in the population is found, copy the genes *///一旦找到种群的最佳个体,就拷贝他的基因for (i = 0; i < NVARS; i++)population[POPSIZE].gene[i] = population[cur_best].gene[i];}/**************************************** ************************//* Elitist function: The best member of the previous generation *//* is stored as the last in the array. If the best member of *//* the current generation is worse then the best member of the *//* previous generation, the latter one would replace the worst *//* member of the current population *//**************************************** ************************///搜寻杰出个体函数:找出最好和最坏的个体。
include <stdio.h>#include<graphics.h>#include <math.h>#include "graph.c"/* 全局变量*/struct individual /* 个体*/{unsigned *chrom; /* 染色体*/double fitness; /* 个体适应度*/double varible; /* 个体对应的变量值*/int xsite; /* 交叉位置*/int parent[2]; /* 父个体*/int *utility; /* 特定数据指针变量*/};struct bestever /* 最佳个体*/{unsigned *chrom; /* 最佳个体染色体*/double fitness; /* 最佳个体适应度*/double varible; /* 最佳个体对应的变量值*/int generation; /* 最佳个体生成代*/};struct individual *oldpop; /* 当前代种群*/struct individual *newpop; /* 新一代种群*/struct bestever bestfit; /* 最佳个体*/double sumfitness; /* 种群中个体适应度累计*/double max; /* 种群中个体最大适应度*/double avg; /* 种群中个体平均适应度*/double min; /* 种群中个体最小适应度*/float pcross; /* 交叉概率*/float pmutation; /* 变异概率*/int popsize; /* 种群大小*/int lchrom; /* 染色体长度*/int chromsize; /* 存储一染色体所需字节数*/int gen; /* 当前世代数*/int maxgen; /* 最大世代数*/int run; /* 当前运行次数*/int maxruns; /* 总运行次数*/int printstrings; /* 输出染色体编码的判断,0 -- 不输出, 1 -- 输出*/int nmutation; /* 当前代变异发生次数*/int ncross; /* 当前代交叉发生次数*//* 随机数发生器使用的静态变量*/static double oldrand[55];static int jrand;static double rndx2;static int rndcalcflag;/* 输出文件指针*/FILE *outfp ;/* 函数定义*/void advance_random();int flip(float);rnd(int, int);void randomize();double randomnormaldeviate();float randomperc(),rndreal(float,float);void warmup_random(float);void initialize(),initdata(),initpop();void initreport(),generation(),initmalloc();void freeall(),nomemory(char *),report();void writepop(),writechrom(unsigned *);void preselect();void statistics(struct individual *);void title(),repchar (FILE *,char *,int);void skip(FILE *,int);int select();void objfunc(struct individual *);int crossover (unsigned *, unsigned *, unsigned *, unsigned *); void mutation(unsigned *);void initialize() /* 遗传算法初始化*/{/* 键盘输入遗传算法参数*/initdata();/* 确定染色体的字节长度*/chromsize = (lchrom/(8*sizeof(unsigned)));if(lchrom%(8*sizeof(unsigned))) chromsize++;/*分配给全局数据结构空间*/initmalloc();/* 初始化随机数发生器*/randomize();/* 初始化全局计数变量和一些数值*/nmutation = 0;ncross = 0;bestfit.fitness = 0.0;bestfit.generation = 0;/* 初始化种群,并统计计算结果*/initpop();statistics(oldpop);initreport();}void initdata() /* 遗传算法参数输入*/{char answer[2];setcolor(9);disp_hz16("种群大小(20-100):",100,150,20);gscanf(320,150,9,15,4,"%d", &popsize);if((popsize%2) != 0){fprintf(outfp, "种群大小已设置为偶数\n");popsize++;};setcolor(9);disp_hz16("染色体长度(8-40):",100,180,20);gscanf(320,180,9,15,4,"%d", &lchrom);setcolor(9);disp_hz16("是否输出染色体编码(y/n):",100,210,20);printstrings=1;gscanf(320,210,9,15,4,"%s", answer);if(strncmp(answer,"n",1) == 0) printstrings = 0;setcolor(9);disp_hz16("最大世代数(100-300):",100,240,20);gscanf(320,240,9,15,4,"%d", &maxgen);setcolor(9);disp_hz16("交叉率(0.2-0.9):",100,270,20);gscanf(320,270,9,15,5,"%f", &pcross);setcolor(9);disp_hz16("变异率(0.01-0.1):",100,300,20);gscanf(320,300,9,15,5,"%f", &pmutation);}void initpop() /* 随机初始化种群*/{int j, j1, k, stop;unsigned mask = 1;for(j = 0; j < popsize; j++){for(k = 0; k < chromsize; k++){oldpop[j].chrom[k] = 0;if(k == (chromsize-1))stop = lchrom - (k*(8*sizeof(unsigned)));elsestop =8*sizeof(unsigned);for(j1 = 1; j1 <= stop; j1++){oldpop[j].chrom[k] = oldpop[j].chrom[k]<<1;if(flip(0.5))oldpop[j].chrom[k] = oldpop[j].chrom[k]|mask;}}oldpop[j].parent[0] = 0; /* 初始父个体信息*/oldpop[j].parent[1] = 0;oldpop[j].xsite = 0;objfunc(&(oldpop[j])); /* 计算初始适应度*/}}void initreport() /* 初始参数输出*/{void skip();skip(outfp,1);fprintf(outfp," 基本遗传算法参数\n");fprintf(outfp," -------------------------------------------------\n");fprintf(outfp," 种群大小(popsize) = %d\n",popsize);fprintf(outfp," 染色体长度(lchrom) = %d\n",lchrom);fprintf(outfp," 最大进化代数(maxgen) = %d\n",maxgen);fprintf(outfp," 交叉概率(pcross) = %f\n", pcross);fprintf(outfp," 变异概率(pmutation) = %f\n", pmutation);fprintf(outfp," -------------------------------------------------\n");skip(outfp,1);fflush(outfp);}void generation(){int mate1, mate2, jcross, j = 0;/* 每代运算前进行预选*/preselect();/* 选择, 交叉, 变异*/do{/* 挑选交叉配对*/mate1 = select();mate2 = select();/* 交叉和变异*/jcross = crossover(oldpop[mate1].chrom, oldpop[mate2].chrom, newpop[j].chrom, newpop[j+1].chrom);mutation(newpop[j].chrom);mutation(newpop[j+1].chrom);/* 解码, 计算适应度*/objfunc(&(newpop[j]));/*记录亲子关系和交叉位置*/newpop[j].parent[0] = mate1+1;newpop[j].xsite = jcross;newpop[j].parent[1] = mate2+1;objfunc(&(newpop[j+1]));newpop[j+1].parent[0] = mate1+1;newpop[j+1].xsite = jcross;newpop[j+1].parent[1] = mate2+1;j = j + 2;}while(j < (popsize-1));}void initmalloc() /*为全局数据变量分配空间*/ {unsigned nbytes;char *malloc();int j;/* 分配给当前代和新一代种群内存空间*/nbytes = popsize*sizeof(struct individual);if((oldpop = (struct individual *) malloc(nbytes)) == NULL)nomemory("oldpop");if((newpop = (struct individual *) malloc(nbytes)) == NULL)nomemory("newpop");/* 分配给染色体内存空间*/nbytes = chromsize*sizeof(unsigned);for(j = 0; j < popsize; j++){if((oldpop[j].chrom = (unsigned *) malloc(nbytes)) == NULL) nomemory("oldpop chromosomes");if((newpop[j].chrom = (unsigned *) malloc(nbytes)) == NULL) nomemory("newpop chromosomes");}if((bestfit.chrom = (unsigned *) malloc(nbytes)) == NULL)nomemory("bestfit chromosome");}void freeall() /* 释放内存空间*/{int i;for(i = 0; i < popsize; i++){free(oldpop[i].chrom);free(newpop[i].chrom);}free(oldpop);free(newpop);free(bestfit.chrom);}void nomemory(string) /* 内存不足,退出*/char *string;{fprintf(outfp,"malloc: out of memory making %s!!\n",string);exit(-1);}void report() /* 输出种群统计结果*/{void repchar(), skip();void writepop(), writestats();repchar(outfp,"-",80);skip(outfp,1);if(printstrings == 1){repchar(outfp," ",((80-17)/2));fprintf(outfp,"模拟计算统计报告\n");fprintf(outfp, "世代数%3d", gen);repchar(outfp," ",(80-28));fprintf(outfp, "世代数%3d\n", (gen+1));fprintf(outfp,"个体染色体编码");repchar(outfp," ",lchrom-5);fprintf(outfp,"适应度父个体交叉位置");fprintf(outfp,"染色体编码");repchar(outfp," ",lchrom-5);fprintf(outfp,"适应度\n");repchar(outfp,"-",80);skip(outfp,1);writepop(outfp);repchar(outfp,"-",80);skip(outfp,1);}fprintf(outfp,"第%d 代统计: \n",gen);fprintf(outfp,"总交叉操作次数= %d, 总变异操作数= %d\n",ncross,nmutation);fprintf(outfp," 最小适应度:%f 最大适应度:%f 平均适应度%f\n", min,max,avg);fprintf(outfp," 迄今发现最佳个体=> 所在代数:%d ", bestfit.generation);fprintf(outfp," 适应度:%f 染色体:", bestfit.fitness);writechrom((&bestfit)->chrom);fprintf(outfp," 对应的变量值: %f", bestfit.varible);skip(outfp,1);repchar(outfp,"-",80);skip(outfp,1);}void writepop(){struct individual *pind;int j;for(j=0; j<popsize; j++){fprintf(outfp,"%3d) ",j+1);/* 当前代个体*/pind = &(oldpop[j]);writechrom(pind->chrom);fprintf(outfp," %8f | ", pind->fitness);/* 新一代个体*/pind = &(newpop[j]);fprintf(outfp,"(%2d,%2d) %2d ",pind->parent[0], pind->parent[1], pind->xsite);writechrom(pind->chrom);fprintf(outfp," %8f\n", pind->fitness);}}void writechrom(chrom) /* 输出染色体编码*/ unsigned *chrom;{int j, k, stop;unsigned mask = 1, tmp;for(k = 0; k < chromsize; k++){tmp = chrom[k];if(k == (chromsize-1))stop = lchrom - (k*(8*sizeof(unsigned)));elsestop =8*sizeof(unsigned);for(j = 0; j < stop; j++){if(tmp&mask)fprintf(outfp,"1");elsefprintf(outfp,"0");tmp = tmp>>1;}}}void preselect(){int j;sumfitness = 0;for(j = 0; j < popsize; j++) sumfitness += oldpop[j].fitness; }int select() /* 轮盘赌选择*/{extern float randomperc();float sum, pick;int i;pick = randomperc();sum = 0;if(sumfitness != 0){for(i = 0; (sum < pick) && (i < popsize); i++)sum += oldpop[i].fitness/sumfitness;}elsei = rnd(1,popsize);return(i-1);}void statistics(pop) /* 计算种群统计数据*/struct individual *pop;{int i, j;sumfitness = 0.0;min = pop[0].fitness;max = pop[0].fitness;/* 计算最大、最小和累计适应度*/for(j = 0; j < popsize; j++){sumfitness = sumfitness + pop[j].fitness;if(pop[j].fitness > max) max = pop[j].fitness;if(pop[j].fitness < min) min = pop[j].fitness;/* new global best-fit individual */if(pop[j].fitness > bestfit.fitness){for(i = 0; i < chromsize; i++)bestfit.chrom[i] = pop[j].chrom[i];bestfit.fitness = pop[j].fitness;bestfit.varible = pop[j].varible;bestfit.generation = gen;}}/* 计算平均适应度*/avg = sumfitness/popsize;}void title(){settextstyle(0,0,4);gprintf(110,15,4,0,"SGA Optimizer");setcolor(9);disp_hz24("基本遗传算法",220,60,25);}void repchar (outfp,ch,repcount)FILE *outfp;char *ch;int repcount;{int j;for (j = 1; j <= repcount; j++) fprintf(outfp,"%s", ch);}void skip(outfp,skipcount)FILE *outfp;int skipcount;{int j;for (j = 1; j <= skipcount; j++) fprintf(outfp,"\n");}void objfunc(critter) /* 计算适应度函数值*/ struct individual *critter;{unsigned mask=1;unsigned bitpos;unsigned tp;double pow(), bitpow ;int j, k, stop;critter->varible = 0.0;for(k = 0; k < chromsize; k++){if(k == (chromsize-1))stop = lchrom-(k*(8*sizeof(unsigned)));elsestop =8*sizeof(unsigned);tp = critter->chrom[k];for(j = 0; j < stop; j++){bitpos = j + (8*sizeof(unsigned))*k;if((tp&mask) == 1){bitpow = pow(2.0,(double) bitpos);critter->varible = critter->varible + bitpow;}tp = tp>>1;}}critter->varible =-1+critter->varible*3/(pow(2.0,(double)lchrom)-1);critter->fitness =critter->varible*sin(critter->varible*10*atan(1)*4)+2.0;}void mutation(unsigned *child) /*变异操作*/{int j, k, stop;unsigned mask, temp = 1;for(k = 0; k < chromsize; k++){mask = 0;if(k == (chromsize-1))stop = lchrom - (k*(8*sizeof(unsigned)));elsestop = 8*sizeof(unsigned);for(j = 0; j < stop; j++){if(flip(pmutation)){mask = mask|(temp<<j);nmutation++;}}child[k] = child[k]^mask;}}int crossover (unsigned *parent1, unsigned *parent2, unsigned *child1, unsigned *child2) /* 由两个父个体交叉产生两个子个体*/{int j, jcross, k;unsigned mask, temp;if(flip(pcross)){jcross = rnd(1 ,(lchrom - 1));/* Cross between 1 and l-1 */ncross++;for(k = 1; k <= chromsize; k++){if(jcross >= (k*(8*sizeof(unsigned)))){child1[k-1] = parent1[k-1];child2[k-1] = parent2[k-1];}else if((jcross < (k*(8*sizeof(unsigned)))) && (jcross > ((k-1)*(8*sizeof(unsigned))))){mask = 1;for(j = 1; j <= (jcross-1-((k-1)*(8*sizeof(unsigned)))); j++){temp = 1;mask = mask<<1;mask = mask|temp;}child1[k-1] = (parent1[k-1]&mask)|(parent2[k-1]&(~mask));child2[k-1] = (parent1[k-1]&(~mask))|(parent2[k-1]&mask);}else{child1[k-1] = parent2[k-1];child2[k-1] = parent1[k-1];}}}else{for(k = 0; k < chromsize; k++){child1[k] = parent1[k];child2[k] = parent2[k];}jcross = 0;}return(jcross);}void advance_random() /* 产生55个随机数*/{int j1;double new_random;for(j1 = 0; j1 < 24; j1++){new_random = oldrand[j1] - oldrand[j1+31];if(new_random < 0.0) new_random = new_random + 1.0;oldrand[j1] = new_random;}for(j1 = 24; j1 < 55; j1++){new_random = oldrand [j1] - oldrand [j1-24];if(new_random < 0.0) new_random = new_random + 1.0;oldrand[j1] = new_random;}}int flip(float prob) /* 以一定概率产生0或1 */{float randomperc();if(randomperc() <= prob)return(1);elsereturn(0);}void randomize() /* 设定随机数种子并初始化随机数发生器*/ {float randomseed;int j1;for(j1=0; j1<=54; j1++)oldrand[j1] = 0.0;jrand=0;do{setcolor(9);disp_hz16("随机数种子[0-1]:",100,330,20);gscanf(320,330,9,15,4,"%f", &randomseed);}while((randomseed < 0.0) || (randomseed > 1.0));warmup_random(randomseed);}double randomnormaldeviate() /* 产生随机标准差*/{double sqrt(), log(), sin(), cos();float randomperc();double t, rndx1;if(rndcalcflag){ rndx1 = sqrt(- 2.0*log((double) randomperc()));t = 6.2831853072 * (double) randomperc();rndx2 = rndx1 * sin(t);rndcalcflag = 0;return(rndx1 * cos(t));}else{rndcalcflag = 1;return(rndx2);}}float randomperc() /*与库函数random()作用相同, 产生[0,1]之间一个随机数*/{jrand++;if(jrand >= 55){jrand = 1;advance_random();}return((float) oldrand[jrand]);}int rnd(low, high) /*在整数low和high之间产生一个随机整数*/int low,high;{int i;float randomperc();if(low >= high)i = low;else{i = (randomperc() * (high - low + 1)) + low;if(i > high) i = high;}return(i);}void warmup_random(float random_seed) /* 初始化随机数发生器*/{int j1, ii;double new_random, prev_random;oldrand[54] = random_seed;new_random = 0.000000001;prev_random = random_seed;for(j1 = 1 ; j1 <= 54; j1++){ii = (21*j1)%54;oldrand[ii] = new_random;new_random = prev_random-new_random;if(new_random<0.0) new_random = new_random + 1.0;prev_random = oldrand[ii];}advance_random();advance_random();advance_random();jrand = 0;}main(argc,argv) /* 主程序*/int argc;char *argv[];{struct individual *temp;FILE *fopen();void title();char *malloc();if((outfp = fopen(argv[1],"w")) == NULL){fprintf(stderr,"Cannot open output file %s\n",argv[1]);exit(-1);}g_init();setcolor(9);title();disp_hz16("输入遗传算法执行次数(1-5):",100,120,20);gscanf(320,120,9,15,4,"%d",&maxruns);for(run=1; run<=maxruns; run++){initialize();for(gen=0; gen<maxgen; gen++){fprintf(outfp,"\n第%d / %d 次运行: 当前代为%d, 共%d 代\n", run,maxruns,gen,maxgen);/* 产生新一代*/generation();/* 计算新一代种群的适应度统计数据*/statistics(newpop);/* 输出新一代统计数据*/report();temp = oldpop;oldpop = newpop;newpop = temp;}freeall();}}。