一个简单实用的遗传算法c程序
- 格式:doc
- 大小:114.00 KB
- 文档页数:19
解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。
基于C语言的遗传算法应用研究介绍遗传算法是一种受生物学启发的优化算法,通过模拟进化过程来寻找最优解。
它被广泛应用于解决各种复杂问题,如组合优化、函数优化、机器学习等领域。
在本文中,我们将讨论基于C语言的遗传算法的应用研究。
遗传算法的原理遗传算法的原理是基于自然选择和遗传机制。
它模拟了生物进化过程中的选择、复制和变异等操作。
算法通过对一个种群进行迭代操作来逐步优化解的质量,直到找到全局最优解或最优近似解。
遗传算法主要包含以下几个关键步骤: 1. 初始化种群:随机生成一组个体作为初始种群。
2. 评估适应度:根据问题的定义,对每个个体计算适应度值。
3.选择操作:根据适应度值选择优秀的个体作为父代。
4. 交叉操作:通过交叉操作,将父代的基因进行混合,生成新的子代。
5. 变异操作:对子代进行变异,引入新的基因信息。
6. 更新种群:用新的个体替代原来的个体,形成新的种群。
7. 终止条件:根据预先设定的终止条件,决定算法是否结束。
C语言在遗传算法中的应用C语言作为一种通用的高级编程语言,具有高效、灵活和可移植的特点,非常适合在遗传算法中实现。
以下是C语言在遗传算法中的几个关键应用。
种群表示C语言可以使用数组或结构体等数据结构来表示遗传算法的种群。
每个个体可以用一个固定长度的二进制串或其他数据类型来表示。
C语言提供了强大的数组操作功能,使得种群的处理和操作更加简便和高效。
适应度函数C语言可以定义适应度函数来评估每个个体的适应度值。
适应度函数根据问题的特定要求来计算一个个体的适应度值,作为选择操作的依据。
C语言提供了丰富的数学函数库,使得适应度函数的计算更加方便。
选择操作C语言可以使用多种选择算法来选择优秀的个体作为父代。
例如,可以使用轮盘赌选择、锦标赛选择等方法来实现选择操作。
C语言提供了条件语句和随机数生成等功能,使得选择操作的实现简单而灵活。
交叉操作C语言可以通过交叉操作将父代的基因混合,生成新的子代。
/*本程序试用遗传算法来解决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;}}。
遗传算法的C语⾔实现(⼆)-----以求解TSP问题为例上⼀次我们使⽤遗传算法求解了⼀个较为复杂的多元⾮线性函数的极值问题,也基本了解了遗传算法的实现基本步骤。
这⼀次,我再以经典的TSP问题为例,更加深⼊地说明遗传算法中选择、交叉、变异等核⼼步骤的实现。
⽽且这⼀次解决的是离散型问题,上⼀次解决的是连续型问题,刚好形成对照。
⾸先介绍⼀下TSP问题。
TSP(traveling salesman problem,旅⾏商问题)是典型的NP完全问题,即其最坏情况下的时间复杂度随着问题规模的增⼤按指数⽅式增长,到⽬前为⽌还没有找到⼀个多项式时间的有效算法。
TSP问题可以描述为:已知n个城市之间的相互距离,某⼀旅⾏商从某⼀个城市出发,访问每个城市⼀次且仅⼀次,最后回到出发的城市,如何安排才能使其所⾛的路线最短。
换⾔之,就是寻找⼀条遍历n个城市的路径,或者说搜索⾃然⼦集X={1,2,...,n}(X的元素表⽰对n个城市的编号)的⼀个排列P(X)={V1,V2,....,Vn},使得Td=∑d(V i,V i+1)+d(V n,V1)取最⼩值,其中,d(V i,V i+1)表⽰城市V i到V i+1的距离。
TSP问题不仅仅是旅⾏商问题,其他许多NP完全问题也可以归结为TSP问题,如邮路问题,装配线上的螺母问题和产品的⽣产安排问题等等,也使得TSP问题的求解具有更加⼴泛的实际意义。
再来说针对TSP问题使⽤遗传算法的步骤。
(1)编码问题:由于这是⼀个离散型的问题,我们采⽤整数编码的⽅式,⽤1~n来表⽰n个城市,1~n的任意⼀个排列就构成了问题的⼀个解。
可以知道,对于n个城市的TSP问题,⼀共有n!种不同的路线。
(2)种群初始化:对于N个个体的种群,随机给出N个问题的解(相当于是染⾊体)作为初始种群。
这⾥具体采⽤的⽅法是:1,2,...,n作为第⼀个个体,然后2,3,..n分别与1交换位置得到n-1个解,从2开始,3,4,...,n分别与2交换位置得到n-2个解,依次类推。
一需求分析1.本程序演示的是用简单遗传算法随机一个种群,然后根据所给的交叉率,变异率,世代数计算最大适应度所在的代数2.演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“提示信息”之后,由用户在键盘上输入演示程序中规定的命令;相应的输入数据和运算结果显示在其后。
3.测试数据输入初始变量后用y=100*(x1*x1-x2)*(x1*x2-x2)+(1-x1)*(1-x1)其中-2.048<=x1,x2<=2.048作适应度函数求最大适应度即为函数的最大值二概要设计1.程序流程图2.类型定义int popsize; //种群大小int maxgeneration; //最大世代数double pc; //交叉率double pm; //变异率struct individualchar 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];3.函数声明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();4.程序的各函数的简单算法说明如下:(1).void generateinitialpopulation ()和void input ()初始化种群和遗传算法参数。
遗传算法程序实现#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);。
C语言人工智能算法实现神经网络和遗传算法人工智能(Artificial Intelligence)是当今科技领域中备受关注的热门话题,而C语言作为一种广泛应用的编程语言,也可以用于实现人工智能算法。
本文将详细介绍如何用C语言来实现神经网络和遗传算法,以展示其在人工智能领域的应用。
1. 神经网络神经网络是一种模仿人脑的学习和决策过程的计算模型。
它由多个神经元组成的层级结构构成,每个神经元接收来自上一层神经元输出的信号,并根据一定的权重和激活函数来计算输出。
下图展示了一个简单的神经网络结构:[图1:神经网络结构图]为了实现一个神经网络,我们需要在C语言中定义神经网络的结构体,并实现前馈传播和反向传播算法。
首先,我们需要定义神经网络的层级结构,可以使用数组或链表来表达。
每个神经元需要存储权重、偏差和激活函数等信息。
我们可以使用结构体来表示神经元的属性,例如:```Ctypedef struct Neuron {double* weights; // 权重数组double bias; // 偏差double output; // 输出} Neuron;```然后,定义神经网络的结构体:```Ctypedef struct NeuralNetwork {int numLayers; // 层数int* layerSizes; // 每层神经元数量的数组Neuron** layers; // 神经元层级的数组} NeuralNetwork;```接下来,我们需要实现神经网络的前馈传播算法。
前馈传播算法用于将输入数据从输入层传递到输出层,并计算网络的输出。
算法的伪代码如下所示:```Cfor each layer in network {for each neuron in layer {calculate neuron's weighted sum of inputs;apply activation function to obtain neuron's output;}}```最后,需要实现神经网络的反向传播算法,用于根据期望输出来调整网络的权重和偏差。
#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);}。
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 Le 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;le;rightPoint=RightPoint;//清空种群容器,以初始化vecPop.clear();for (int i=0; i<popSize; i++){//类的构造函数已经把适应性评分初始化为0vecPop.push_back(Genome());//把所有的基因编码初始化为函数区间内的随机数。
此例程总共包含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());//把所有的基因编码初始化为函数区间内的随机数。
一个简单实用的遗传算法c程序(转载)c++ 2009-07-28 23:09:03 阅读418 评论0 字号:大中小这是一个非常简单的遗传算法源代码,是由Denis Cormier (North Carolina State University)开发的,Sita S.Raghavan (University of North Carolina at Charlotte)修正。
代码保证尽可能少,实际上也不必查错。
对一特定的应用修正此代码,用户只需改变常数的定义并且定义“评价函数”即可。
注意代码的设计是求最大值,其中的目标函数只能取正值;且函数值和个体的适应值之间没有区别。
该系统使用比率选择、精华模型、单点杂交和均匀变异。
如果用Gaussian变异替换均匀变异,可能得到更好的效果。
代码没有任何图形,甚至也没有屏幕输出,主要是保证在平台之间的高可移植性。
读者可以从,目录 coe/evol中的文件prog.c中获得。
要求输入的文件应该命名为‘gadata.txt’;系统产生的输出文件为‘galog.txt’。
输入的文件由几行组成:数目对应于变量数。
且每一行提供次序——对应于变量的上下界。
如第一行为第一个变量提供上下界,第二行为第二个变量提供上下界,等等。
/************************************************************************** //* This is a simple genetic algorithm implementation where the *//* evaluation function takes positive values only and the *//* fitness of an individual is the same as the value of the *//* objective function *//************************************************************************** /#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 */#define 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 */ /****************************************************************/ void elitist(){int i;double best, worst; /* best and worst fitness values */ int best_mem, worst_mem; /* indexes of the best and worst member */ best = population[0].fitness;worst = population[0].fitness;for (i = 0; i < POPSIZE - 1; ++i){if(population[i].fitness > population[i+1].fitness){if (population[i].fitness >= best){best = population[i].fitness;best_mem = i;}if (population[i+1].fitness <= worst) {worst = population[i+1].fitness; worst_mem = i + 1;}}else{if (population[i].fitness <= worst){worst = population[i].fitness; worst_mem = i;}if (population[i+1].fitness >= best) {best = population[i+1].fitness; best_mem = i + 1;}}}/* if best individual from the new population is better than *//* the best individual from the previous population, then *//* copy the best from the new population; else replace the *//* worst individual from the current population with the *//* best one from the previous generation */if (best >= population[POPSIZE].fitness){for (i = 0; i < NVARS; i++)population[POPSIZE].gene[i] = population[best_mem].gene[i]; population[POPSIZE].fitness = population[best_mem].fitness;}else{for (i = 0; i < NVARS; i++)population[worst_mem].gene[i] = population[POPSIZE].gene[i]; population[worst_mem].fitness = population[POPSIZE].fitness;}}/**************************************************************//* Selection function: Standard proportional selection for *//* maximization problems incorporating elitist model - makes *//* sure that the best member survives */ /**************************************************************/ void select(void){int mem, i, j, k;double sum = 0;double p;/* find total fitness of the population */for (mem = 0; mem < POPSIZE; mem++){sum += population[mem].fitness;}/* calculate relative fitness */for (mem = 0; mem < POPSIZE; mem++){population[mem].rfitness = population[mem].fitness/sum; }population[0].cfitness = population[0].rfitness;/* calculate cumulative fitness */for (mem = 1; mem < POPSIZE; mem++){population[mem].cfitness = population[mem-1].cfitness + population[mem].rfitness;}/* finally select survivors using cumulative fitness. */for (i = 0; i < POPSIZE; i++){p = rand()%1000/1000.0;if (p < population[0].cfitness)newpopulation[i] = population[0];else{for (j = 0; j < POPSIZE;j++)if (p >= population[j].cfitness &&p<population[j+1].cfitness)newpopulation[i] = population[j+1];}}/* once a new population is created, copy it back */for (i = 0; i < POPSIZE; i++)population[i] = newpopulation[i];}/***************************************************************/ /* Crossover selection: selects two parents that take part in */ /* the crossover. Implements a single point crossover */ /***************************************************************/ void crossover(void){int i, mem, one;int first = 0; /* count of the number of members chosen */ double x;for (mem = 0; mem < POPSIZE; ++mem){x = rand()%1000/1000.0;if (x < PXOVER){++first;if (first % 2 == 0)Xover(one, mem);elseone = mem;}}}/**************************************************************/ /* Crossover: performs crossover of the two selected parents. */ /**************************************************************/ void Xover(int one, int two){int i;int point; /* crossover point *//* select crossover point */if(NVARS > 1){if(NVARS == 2)point = 1;elsepoint = (rand() % (NVARS - 1)) + 1;for (i = 0; i < point; i++)swap(&population[one].gene[i], &population[two].gene[i]); }}/*************************************************************/ /* Swap: A swap procedure that helps in swapping 2 variables *//*************************************************************/ void swap(double *x, double *y){double temp;temp = *x;*x = *y;*y = temp;}/**************************************************************/ /* Mutation: Random uniform mutation. A variable selected for */ /* mutation is replaced by a random value between lower and */ /* upper bounds of this variable */ /**************************************************************/ void mutate(void){int i, j;double lbound, hbound;double x;for (i = 0; i < POPSIZE; i++)for (j = 0; j < NVARS; j++){x = rand()%1000/1000.0;if (x < PMUTATION){/* find the bounds on the variable to be mutated */ lbound = population[i].lower[j];hbound = population[i].upper[j];population[i].gene[j] = randval(lbound, hbound);}}}/***************************************************************//* Report function: Reports progress of the simulation. Data *//* dumped into the output file are separated by commas *//***************************************************************/void report(void){int i;double best_val; /* best population fitness */double avg; /* avg population fitness */double stddev; /* std. deviation of population fitness */ double sum_square; /* sum of square for std. calc */double square_sum; /* square of sum for std. calc */ double sum; /* total population fitness */sum = 0.0;sum_square = 0.0;for (i = 0; i < POPSIZE; i++){sum += population[i].fitness;sum_square += population[i].fitness * population[i].fitness; }avg = sum/(double)POPSIZE;square_sum = avg * avg * POPSIZE;stddev = sqrt((sum_square - square_sum)/(POPSIZE - 1));best_val = population[POPSIZE].fitness;fprintf(galog, "\n%5d, %6.3f, %6.3f, %6.3f \n\n", generation, best_val, avg, stddev);}/**************************************************************/ /* Main function: Each generation involves selecting the best */ /* members, performing crossover & mutation and then */ /* evaluating the resulting population, until the terminating */ /* condition is satisfied *//**************************************************************/ void main(void){int i;if ((galog = fopen("galog.txt","w"))==NULL){exit(1);}generation = 0;fprintf(galog, "\n generation best average standard \n"); fprintf(galog, " number value fitness deviation \n"); initialize();evaluate();keep_the_best();while(generation<MAXGENS){generation++;select();crossover();mutate();report();evaluate();elitist();}fprintf(galog,"\n\n Simulation completed\n");fprintf(galog,"\n Best member: \n");for (i = 0; i < NVARS; i++){fprintf (galog,"\n var(%d) = %3.3f",i,population[POPSIZE].gene[i]);}fprintf(galog,"\n\n Best fitness = %3.3f",population[POPSIZE].fitness);fclose(galog);printf("Success\n");}/***************************************************************/链接库文件?这个简单一般的第三方库文件有2种提供方式 1.lib静态库,这样必须在工程设置里面添加。
遗传算法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 *//**************************************** ************************///搜寻杰出个体函数:找出最好和最坏的个体。
遗传算法简单c#程序实现(非专业)副本2using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 张小叶叶{//求下列元素的最大值:目标函数max=f(x1,x2)=x1*x1+x2*x2;取值范围在{1,2,3,4,5,6,7}//本算法在选择时使用:轮盘赌选择法、交叉时使用:单点交叉。
class Program{static int groupscale;//种群规模static int variation;//变异概率static int n;static int x1 = 1;//基因组数(便于对两组基因进行区分)static int x2 = 2;int result;static void Main(string[] args){Program p = new Program();Console.WriteLine("请输入种群规模?");groupscale = input();Console.WriteLine("请输入变异概率?");variation = input();Console.Write("产生随机数:\n");//产生二进制数int[,] arrnum1 = new int[groupscale, 3];//二进制随机数组x1int[,] arrnum2 = new int[groupscale, 3];//二进制随机数组x1getrand(groupscale, ref arrnum1, ref arrnum2);Console.WriteLine("二进制转十进制的结果是:");//返回一维数组就是两组,种群规模个,十进制数(转十进制便于进行适应度计算)int[] tennum1 = convert(groupscale, x1, arrnum1);//十进制随机数组x1int[] tennum2 = convert(groupscale, x2, arrnum2);//十进制随机数组x2Console.WriteLine("适应度的计算:");int[] one = max(groupscale, tennum1, tennum2,out p.result);//个体适应度int zuidazhi = promax(one);Console.WriteLine("适应度总和是:{0}",p.result);double[] sumprob = probablity(one, groupscale, p.result);//累积适应度概率double[] random = rand(groupscale);//0-1随机数的产生Console.WriteLine("选择出的群体:");int[] chooseDNA=choose(groupscale, random, sumprob);//得到被选中的数在数组中的位置int[,] answer=ans(arrnum1, arrnum2, chooseDNA);//得出选择结果Console.WriteLine("单点交叉后的群体:");int[,] jcanswer = jiaocha(groupscale, answer);shuchu(jcanswer);Console.WriteLine("变异后的群体:");int[,] varanswer = var(variation, jcanswer);shuchu(varanswer);Console.WriteLine("请输入还需循环代数?");n = input();for (int i = 0; i < n; i++){fenzu(varanswer, ref arrnum1, ref arrnum2);tennum1 = convert(groupscale, x1, arrnum1);tennum2 = convert(groupscale, x2, arrnum2);one = max(groupscale, tennum1, tennum2, out p.result);zuidazhi = promax(one);sumprob = probablity(one, groupscale, p.result);random = rand(groupscale);chooseDNA = choose(groupscale, random, sumprob);answer = ans(arrnum1, arrnum2, chooseDNA);jcanswer = jiaocha(groupscale, answer);varanswer = var(variation, jcanswer);Console.WriteLine("第{0}代产生的子种群是:",i+2);shuchu(varanswer);}Console.ReadKey();}//通用输入inputpublic static int input(){int a;while (!int.TryParse(Console.ReadLine(), out a)){Console.WriteLine("格式错误,请输入整数");}return a;}//随机产生个体(产生的二进制随机数,数组内元素个数=种群规模,并要求对产生的随机数进行编号,使用二维数组)public static void getrand(int s, ref int[,] s1, ref int[,] s2){s1 = new int[s, 3];s2 = new int[s, 3];Random rand = new Random();Console.WriteLine("第一组随机数x1\t");for (int i = 0; i < s; i++){for (int j = 0; j < 3; j++){s1[i, j] = rand.Next(0, 2);Console.Write(s1[i, j]);}Console.WriteLine("\t");}Console.WriteLine("第二组随机数x2\t");for (int i = 0; i < s; i++){for (int k = 0; k < 3; k++){s2[i, k] = rand.Next(0, 2);Console.Write(s2[i, k]);}Console.WriteLine("\t");}}//二进制编码成十进制public static int[] convert(int s, int s2, int[,] arrnum) {Console.WriteLine("第{0}组十进制数是:", s2);int[] ten = new int[s];for (int i = 0; i < s; i++)int result = 0;for (int j = 0; j < 3; j++){result += (int)Math.Pow((double)2, (double)2 - j) * arrnum[i, j];}ten[i] = result;Console.Write("{0}\t", ten[i]);}Console.WriteLine(" \n");return ten;}//适应度计算public static int[] max(int s, int[] s1, int[] s2,out int result){int[] one = new int[s];result = 0;for (int k = 0; k < groupscale; k++){one[k] = (int)Math.Pow((double)s1[k], (double)2) + (int)Math.Pow((double)s2[k], (double)2);Console.WriteLine("第{0}个初始种群适应度为:{1}", k + 1, one[k]);result += one[k];}return one;}//适应度概率计算及累积适应度概率public static double [] probablity(int[] s,int a,int sum)double [] p=new double [a];double[] sump = new double[a+1];sump[0] = 0;for (int i = 0; i{p[i] = (double)s[i] / (double)sum;sump[i+1]=p[i]+sump[i];Console.WriteLine("第{0}个初始种群适应概率为:{1:0.00},累积适应度概率为{2:0.00}",i+1,p[i],sump[i+1]);}return sump;}//0-1之间的随机数的产生public static double[] rand(int s){int[] ran= new int[s];double[] rand=new double[s];Random a = new Random();for (int i = 0; i < s; i++){ran[i] = a.Next(0, 1000);rand[i]= (double)ran[i]/ (double)1000;}return rand;}//进行选择(1,得到被选中的数在数组中的位置2,得到被选中的二进制数组)public static int[] choose(int s,double[] s1,double[] s2){int[] chooseDNA = new int[s];for (int i = 0; i < s; i++){for (int k = 1; k < s+1; k++){if (s2[k - 1] <=s1[i] && s2[k] > s1[i]){chooseDNA[i] = k;}}}return chooseDNA;}public static int[,] ans(int[,] s1,int[,] s2,int[] s) {int[,] answer = new int[s.Length, 6];for (int i = 0; i < s.Length; i++){int a = s[i] - 1;for (int j = 0; j < 3; j++){Console.Write(s1[a, j]);answer[i, j] = s1[a, j];}for (int k = 0; k < 3; k++){Console.Write(s2[a, k]);answer[i, 3 + k] = s2[a, k];}Console.WriteLine("\n");}return answer;}//单点交叉,假定交叉率为100%public static int[,] jiaocha(int s, int[,] a){//群体进行随机配对,产生随机交叉点,相互交换染色体的基因Random ran = new Random();int[] random = new int[s / 2];if (s % 2 == 0){for (int i = 0; i < s / 2; i++){random[i] = ran.Next(1, 6);for (int j = 0; j < random[i]; j++){int[,] c = new int[s, 6];c[i, j] = a[i, j];a[i, j] = a[(s / 2)+i, j];a[(s / 2) + i, j] = c[i, j];}}}else{for (int i = 0; i < s / 2; i++){random[i] = ran.Next(1, 6);for (int j = 0; j < random[i]; j++){int[,] c = new int[(s - 1) / 2, 6];c[i, j] = a[i, j];a[i, j] = a[(s - 1) / 2, j];a[(s - 1) / 2, j] = c[i, j];}}}return a;}public static void shuchu(int[,] a) {for (int i = 0; i < groupscale; i++) {for (int j = 0; j < 6; j++){Console.Write(a[i, j]);}Console.WriteLine("\n");}}//变异public static int[,] var(int a,int[,] s) {//二维转一维int[] s1 = new int[groupscale * 6]; for (int i = 0; i < groupscale; i++) {for (int j = 0; j < 6; j++){s1[i * 6 + j] = s[i, j];}}if (groupscale * 6 * a * 0.01 < 1){Console.WriteLine("变异概率过小,不发生变异");}else{int b = Convert.ToInt32(Math.Floor(groupscale * 6 * a * 0.01)); Random ran = new Random();int[] c = new int[b];for (int i = 0; i < b; i++){c[i] = ran.Next(0, groupscale * 6);if (s1[c[i]] == 0){s1[c[i]] = 1;}else{s1[c[i]] = 0;}}}//一维转二维for (int i = 0; i < groupscale; i++){for (int j = 0; j < 6; j++){s[i, j] = s1[i * 6 + j];}return s;}//进行分组public static void fenzu(int[,] s,ref int[,] s1,ref int[,] s2) {s1 = new int[groupscale, 3];s2 = new int[groupscale, 3];for (int i = 0; i < groupscale; i++){for (int k = 0; k < 3; k++){s1[i, k] = s[i, k];}for (int j = 0; j < 3; j++){s2[i, j] = s[i, j + 3];}}}//适应度最大值public static int promax(int[] a){int max = 0;for (int i = 0; i < groupscale; i++){if (a[i]>max){max = a[i];}Console.WriteLine("适应度最大值为{0}", max); return max;}}}。
简单函数优化的遗传算法C语言程序所在学院:信息工程学院专业名称:计算机科学与技术所在班级: 09计科(2)班小组成员:王鹏远(200915074)二〇一二年六月六日简单函数优化的遗传算法遗传算法(Genetic Algorithm)是由美国Michigan大学的Holland 教授(1969)提出,后经由De Jong(1975),Goldberg(1989)等归纳总结所形成的一类模拟进化算法。
遗传算法搜索最优解的方法是模仿生物的进化过程,即通过选择与染色体之间的交叉和变异来完成的。
遗传算法主要使用选择算子、交叉算子与变异算子来模拟生物进化,从而产生一代又一代的种群。
函数优化是遗传算法的经典应用领域之一,也是对遗传算法进行性能评价的衡量指标之一。
下面是一个简单函数优化的遗传算法C语言程序。
//***************************************************************************** //This is a simple genetic algorithm implementation for function optimization//***************************************************************************** #include <iostream.h>#include <stdio.h>#include <stdlib.h>#include <math.h>#include <time.h>//Parametes setting#define POPSIZE 50 // population size 染色体个数#define MAXGENS 10000 // max number of generations 迭代次数#define NVARS 2 // no of problem variables 变量个数#define PXOVER 0.75 // probability of crossover 交叉概率#define PMUTA TION 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[NV ARS]; // a string of variables 一连串变量double fitness; // individual's fitness 个体适应度double upper[NV ARS]; // individual's variables upper bound 个体上界double lower[NV ARS]; // individual's variables lower bound 个体下界double rfitness; // relative fitness 相关适应度等于个体适应度除以//所有个体适应度之和double cfitness; // cumulative fitness 累积适应度是相关适应度的累积};//声明个体struct genotype population[POPSIZE+1]; // populationstruct 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 all fitness for each number of the population//*****************************************************************************void initialize(void){int i,j;double lbound,ubound;for(i=0;i<NV ARS;i++){lbound=-5.0;ubound=5.0;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]);}}}//每个变量初始popsize个个体//***************************************************************************** // Random value generator: Generates a value within bounds//***************************************************************************** //randval随机定义域内取值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.// The current function is: x[1]^2-x[1]*x[2]+x[3] 目标函数// Each time this is changed, the code has to be recompiled.//***************************************************************************** void evaluate(void){int mem;int i;double x[NV ARS+1];for (mem = 0; mem < POPSIZE; mem++){for (i = 0; i < NV ARS; 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.//***************************************************************************** //最好个体函数保持副本void keep_the_best(){int mem;int i;cur_best = 0; // stores the index of the best individualfor (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 genesfor (i = 0; i < NV ARS; 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 individual from the new population is better// than the best individual from the previous population, then copy the best// from the new population; else replace the worst individual from the current// population with the best one from the previous generation.//***************************************************************************** //当前代数的最好个体和目前已找到的最好个体比较//最好的保存下来,最差的淘汰void elitist(){int i;double best, worst; // best and worst fitness valuesint best_mem, worst_mem; // indexes of the best and worst memberbest = population[0].fitness;worst = population[0].fitness;for (i = 0; i < POPSIZE - 1; ++i){if(population[i].fitness > population[i+1].fitness){if (population[i].fitness >= best){best = population[i].fitness;best_mem = i;}if (population[i+1].fitness <= worst){worst = population[i+1].fitness;worst_mem = i + 1;}}else{if (population[i].fitness <= worst){worst = population[i].fitness;worst_mem = i;}if (population[i+1].fitness >= best){best = population[i+1].fitness;best_mem = i + 1;}}}// if best individual from the new population is better than// the best individual from the previous population, then// copy the best from the new population; else replace the// worst individual from the current population with the// best one from the previous generationif (best >= population[POPSIZE].fitness){for (i = 0; i < NV ARS; i++)//取代当前已找到最好的个体population[POPSIZE].gene[i] = population[best_mem].gene[i];population[POPSIZE].fitness = population[best_mem].fitness;}else{for (i = 0; i < NV ARS; i++) //淘汰当代中最差的个体population[worst_mem].gene[i] = population[POPSIZE].gene[i];population[worst_mem].fitness = population[POPSIZE].fitness;}}//***************************************************************************** // Selection function: Standard proportional selection for maximization problems// incorporating elitist model - makes sure that the best member survives//***************************************************************************** // 比例选择void select(void){int mem, i, j, k;double sum = 0;double p;// find total fitness of the populationfor (mem = 0; mem < POPSIZE; mem++){sum += population[mem].fitness;}// calculate relative fitness// 相关适应度等于个体适应度除以所有个体适应度之和for (mem = 0; mem < POPSIZE; mem++){population[mem].rfitness = population[mem].fitness/sum;}population[0].cfitness = population[0].rfitness;// calculate cumulative fitnessfor (mem = 1; mem < POPSIZE; mem++){population[mem].cfitness = population[mem-1].cfitness +population[mem].rfitness;}// finally select survivors using cumulative fitness.// 选择依据累积适应度for (i = 0; i < POPSIZE; i++){p = rand()%1000/1000.0;if (p < population[0].cfitness)newpopulation[i] = population[0];else{for (j = 0; j < POPSIZE;j++)if (p >= population[j].cfitness && p<population[j+1].cfitness)newpopulation[i] = population[j+1];}}// once a new population is created, copy it backfor (i = 0; i < POPSIZE; i++)population[i] = newpopulation[i];}//*****************************************************************************// Crossover selection: selects two parents that take part in the crossover.// Implements a single point crossover//***************************************************************************** //单点交叉void crossover(void){int i, mem, one;int first = 0; // count of the number of members chosendouble x;for (mem = 0; mem < POPSIZE; ++mem){x = rand()%1000/1000.0;if (x < PXOVER){++first;if (first % 2 == 0)Xover(one, mem);elseone = mem;}}}//***************************************************************************** // Crossover: performs crossover of the two selected parents.//*****************************************************************************void Xover(int one, int two){int i;int point; // crossover point// select crossover pointif(NV ARS > 1){if(NV ARS == 2)point = 1;elsepoint = (rand() % (NV ARS - 1)) + 1;for (i = 0; i < point; i++)swap(&population[one].gene[i], &population[two].gene[i]);}}//***************************************************************************** // Swap: A swap procedure that helps in swapping 2 variables//*****************************************************************************void swap(double *x, double *y){double temp;temp = *x;*x = *y;*y = temp;}//***************************************************************************** // Mutation functon: Random uniform mutation. A variable selected for mutation// is replaced by a random value between lower and upper bounds of this variable//***************************************************************************** //随机均匀变异void mutate(void){int i, j;double lbound, hbound;double x;for (i = 0; i < POPSIZE; i++)for (j = 0; j < NV ARS; j++){x = rand()%1000/1000.0;if (x < PMUTATION){// find the bounds on the variable to be mutatedlbound = population[i].lower[j];hbound = population[i].upper[j];population[i].gene[j] = randval(lbound, hbound);}}}//***************************************************************************** // Report function: Reports progress of the simulation.//***************************************************************************** void report(void)int i;double best_val; // best population fitnessdouble avg; // avg population fitnessdouble stddev; // std. deviation of population fitness 偏差double sum_square; // sum of square for std. calcdouble square_sum; // square of sum for std. calcdouble sum; // total population fitnesssum = 0.0;sum_square = 0.0;for (i = 0; i < POPSIZE; i++){sum += population[i].fitness;sum_square += population[i].fitness * population[i].fitness;}avg = sum/(double)POPSIZE;square_sum = avg * avg * POPSIZE;stddev = sqrt((sum_square - square_sum)/(POPSIZE - 1));best_val = population[POPSIZE].fitness;fprintf(galog, "\n%5d, %6.3f, %6.3f, %6.3f \n\n", generation, best_val, avg, stddev);}//***************************************************************************** // Main function: Each generation involves selecting the best members, performing// crossover & mutation and then evaluating the resulting population, until the// terminating condition is satisfied.//***************************************************************************** void main(void){int i;if ((galog = fopen("galog.txt","w"))==NULL){exit(1);}generation = 0;srand(time(NULL));fprintf(galog, " number value fitness deviation \n");printf("\n generation best average standard \n");initialize();//初始化evaluate();//评估keep_the_best();while(generation<MAXGENS){generation++;select();crossover();mutate();report();evaluate();elitist();//保存最好的,淘汰最差的}fprintf(galog,"\n\n Simulation completed\n");fprintf(galog,"\n Best member: \n");printf("\n Best member: \n");for (i = 0; i < NV ARS; i++){fprintf (galog,"\n var(%d) = %3.3f",i,population[POPSIZE].gene[i]);printf("\n var(%d)=%3.3f",i,population[POPSIZE].gene[i]);}fprintf(galog,"\n\n Best fitness = %3.3f",population[POPSIZE].fitness);fclose(galog);printf("\n\n Best fitness = %3.3f\n",population[POPSIZE].fitness);printf(" Success\n");}//***************************************************************************** 程序运行结果如下图所示:控制台输出文件输出结果galog.txt文件输出结果galog.txt通过本次简单函数优化的遗传算法的编程实现,我们从中体会到了遗传算法的运算过程。
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();}}。
一个简单实用的遗传算法c程序(转载)c++ 2009-07-28 23:09:03 阅读418 评论0 字号:大中小这是一个非常简单的遗传算法源代码,是由Denis Cormier (North Carolina State University)开发的,Sita S.Raghavan (University of North Carolina at Charlotte)修正。
代码保证尽可能少,实际上也不必查错。
对一特定的应用修正此代码,用户只需改变常数的定义并且定义“评价函数”即可。
注意代码的设计是求最大值,其中的目标函数只能取正值;且函数值和个体的适应值之间没有区别。
该系统使用比率选择、精华模型、单点杂交和均匀变异。
如果用Gaussian变异替换均匀变异,可能得到更好的效果。
代码没有任何图形,甚至也没有屏幕输出,主要是保证在平台之间的高可移植性。
读者可以从,目录coe/evol 中的文件prog.c中获得。
要求输入的文件应该命名为‘gadata.txt’;系统产生的输出文件为‘galog.txt’。
输入的文件由几行组成:数目对应于变量数。
且每一行提供次序——对应于变量的上下界。
如第一行为第一个变量提供上下界,第二行为第二个变量提供上下界,等等。
/**************************************************************************//* This is a simple genetic algorithm implementation where the *//* evaluation function takes positive values only and the *//* fitness of an individual is the same as the value of the *//* objective function *//**************************************************************************/#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 */#define 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 */ /****************************************************************/void elitist(){int i;double best, worst; /* best and worst fitness values */int best_mem, worst_mem; /* indexes of the best and worst member */ best = population[0].fitness;worst = population[0].fitness;for (i = 0; i < POPSIZE - 1; ++i){if(population[i].fitness > population[i+1].fitness){if (population[i].fitness >= best){best = population[i].fitness;best_mem = i;}if (population[i+1].fitness <= worst){worst = population[i+1].fitness;worst_mem = i + 1;}}else{if (population[i].fitness <= worst){worst = population[i].fitness;worst_mem = i;}if (population[i+1].fitness >= best){best = population[i+1].fitness;best_mem = i + 1;}}}/* if best individual from the new population is better than */ /* the best individual from the previous population, then *//* copy the best from the new population; else replace the *//* worst individual from the current population with the *//* best one from the previous generation */if (best >= population[POPSIZE].fitness){for (i = 0; i < NVARS; i++)population[POPSIZE].gene[i] = population[best_mem].gene[i];population[POPSIZE].fitness = population[best_mem].fitness;}else{for (i = 0; i < NVARS; i++)population[worst_mem].gene[i] = population[POPSIZE].gene[i];population[worst_mem].fitness = population[POPSIZE].fitness;}}/**************************************************************//* Selection function: Standard proportional selection for *//* maximization problems incorporating elitist model - makes *//* sure that the best member survives *//**************************************************************/void select(void){int mem, i, j, k;double sum = 0;double p;/* find total fitness of the population */for (mem = 0; mem < POPSIZE; mem++){sum += population[mem].fitness;}/* calculate relative fitness */for (mem = 0; mem < POPSIZE; mem++){population[mem].rfitness = population[mem].fitness/sum;}population[0].cfitness = population[0].rfitness;/* calculate cumulative fitness */for (mem = 1; mem < POPSIZE; mem++){population[mem].cfitness = population[mem-1].cfitness +population[mem].rfitness;}/* finally select survivors using cumulative fitness. */for (i = 0; i < POPSIZE; i++){p = rand()%1000/1000.0;if (p < population[0].cfitness)newpopulation[i] = population[0];else{for (j = 0; j < POPSIZE;j++)if (p >= population[j].cfitness &&p<population[j+1].cfitness)newpopulation[i] = population[j+1];}}/* once a new population is created, copy it back */for (i = 0; i < POPSIZE; i++)population[i] = newpopulation[i];}/***************************************************************//* Crossover selection: selects two parents that take part in *//* the crossover. Implements a single point crossover */ /***************************************************************/void crossover(void){int i, mem, one;int first = 0; /* count of the number of members chosen */ double x;for (mem = 0; mem < POPSIZE; ++mem){x = rand()%1000/1000.0;if (x < PXOVER){++first;if (first % 2 == 0)Xover(one, mem);elseone = mem;}}}/**************************************************************//* Crossover: performs crossover of the two selected parents. *//**************************************************************/void Xover(int one, int two){int i;int point; /* crossover point *//* select crossover point */if(NVARS > 1){if(NVARS == 2)point = 1;elsepoint = (rand() % (NVARS - 1)) + 1;for (i = 0; i < point; i++)swap(&population[one].gene[i], &population[two].gene[i]);}}/*************************************************************//* Swap: A swap procedure that helps in swapping 2 variables */ /*************************************************************/void swap(double *x, double *y){double temp;temp = *x;*x = *y;*y = temp;}/**************************************************************//* Mutation: Random uniform mutation. A variable selected for *//* mutation is replaced by a random value between lower and */ /* upper bounds of this variable */ /**************************************************************/void mutate(void){int i, j;double lbound, hbound;double x;for (i = 0; i < POPSIZE; i++)for (j = 0; j < NVARS; j++){x = rand()%1000/1000.0;if (x < PMUTATION){/* find the bounds on the variable to be mutated */lbound = population[i].lower[j];hbound = population[i].upper[j];population[i].gene[j] = randval(lbound, hbound);}}}/***************************************************************//* Report function: Reports progress of the simulation. Data *//* dumped into the output file are separated by commas */ /***************************************************************/void report(void){int i;double best_val; /* best population fitness */double avg; /* avg population fitness */double stddev; /* std. deviation of population fitness */ double sum_square; /* sum of square for std. calc */ double square_sum; /* square of sum for std. calc */ double sum; /* total population fitness */sum = 0.0;sum_square = 0.0;for (i = 0; i < POPSIZE; i++){sum += population[i].fitness;sum_square += population[i].fitness * population[i].fitness;}avg = sum/(double)POPSIZE;square_sum = avg * avg * POPSIZE;stddev = sqrt((sum_square - square_sum)/(POPSIZE - 1));best_val = population[POPSIZE].fitness;fprintf(galog, "\n%5d, %6.3f, %6.3f, %6.3f \n\n", generation,best_val, avg, stddev); }/**************************************************************//* Main function: Each generation involves selecting the best *//* members, performing crossover & mutation and then */ /* evaluating the resulting population, until the terminating *//* condition is satisfied */ /**************************************************************/void main(void){int i;if ((galog = fopen("galog.txt","w"))==NULL){exit(1);}generation = 0;fprintf(galog, "\n generation best average standard \n"); fprintf(galog, " number value fitness deviation \n"); initialize();evaluate();keep_the_best();while(generation<MAXGENS){generation++;select();crossover();mutate();report();evaluate();elitist();}fprintf(galog,"\n\n Simulation completed\n");fprintf(galog,"\n Best member: \n");for (i = 0; i < NVARS; i++){fprintf (galog,"\n var(%d) = %3.3f",i,population[POPSIZE].gene[i]);}fprintf(galog,"\n\n Best fitness = %3.3f",population[POPSIZE].fitness);fclose(galog);printf("Success\n");}/***************************************************************/链接库文件?这个简单一般的第三方库文件有2种提供方式1.lib静态库,这样必须在工程设置里面添加。