PDA

View Full Version : Thuật giải di truyền



hoangblack1
09-03-2010, 10:44
mình đang làm "bài toán cực tiểu hàm F với N biến vào liên tục" bằng thuật giải di truyền.nhưng khó quá.các bạn tham khảo và giup mình phát triển bài toán với nha.đây la code của chương trình:
#include<time.h>
#include<stdlib.h>
#include<conio.h>
#include<stdio.h>
#include<math.h>
/*xac dinh gia tri thich nghi*/
float scalepop(float*obj,float *fit,int popsize)
{
float a,b,min,ave,max,sum,ob[100];
int i;
sum=max=-1.0e37;min=1.0e37;
for(i=0;i<popsize;i++) if(sum<obj[i]) sum=obj[i];
for(ave=0,i=0;i<popsize;i++)

{
obj[i]=sum-obj[i];
if(max<obj[i]) max=ob[i];
if(min<ob[i]) min=ob[i];
ave+=ob[i];
}
ave/=popsize;
if(min>(2*ave-max))
{
a=ave/(max-ave);
b=a*(max-2*ave);
}
else
{
a=ave/(ave-min);
b=-min*a;
}
for(sum=1,i=0;i<popsize;i++)
{
fit[i]=a*ob[i]+b;
sum+=fit[i];
}
return sum;
}
/*tao gia tri ngau nhien*/
float random01()
{
float s;
s=random(30000)/30000.0;
return s;
}
int flip(float p)
{
if(random01()<p) return 1;
else return 0;
}
/*toan tu lua chon ca the*/
int select(float *fit,float sum,int popsize)
{
float partsum,rand;
int i,j=popsize-1;
rand=random01()*sum;
for(partsum=0,j=0;j<popsize;j++)
{
partsum+=fit[j];
if(partsum>=rand) {i=j;break;}

}
return i;
}
/*toan tu dot bien*/
char mutation(char c,float pmu)
{
char s;
if(flip(pmu))
{
if(c) s=0;
else s=1;
}
else s=c;
return s;
}
/*toan tu lai ghep*/
void crossover(char *parent1,char *parent2,char *child1,char *child2,
int lchrom,float pcross,float pmu,int n)
{
int j,jcross,i;
for(i=0;i<n;i++)
{
if(flip(pcross))
{ jcross=random(lchrom); }
else jcross=lchrom;
for(j=0;j<jcross;j++)
{
child1[i*lchrom+j]=mutation(parent1[i*lchrom+j],pmu);
child2[i*lchrom+j]=mutation(parent2[i*lchrom+j],pmu);
}
for(j=jcross;j<lchrom;j++)
{
child1[i*lchrom+j]=mutation(parent2[i*lchrom+j],pmu);
child2[i*lchrom+j]=mutation(parent1[i*lchrom+j],pmu);
}
}
}
/*khoi tao quan the*/
void initpop(char pop[100][250],int popsize,int lchrom)
{
int i,j;
for(i=0;i<popsize;i++)
{
for(j=0;j<lchrom;j++)
{
pop[i][j]=flip(0.5);
}
}
}
/*tai san xuat quan the*/
void reproduction(char oldpop[100][250],char newpop[100][250],int popsize,int lchrom)
{
int i,j;
for(i=0;i<popsize;i++)
{
for(j=0;j<lchrom;j++)
{ oldpop[i][j]=newpop[i][j]; }
}
}
/*thuc hien qua trinh tien hoa*/
void generate(char oldpop[100][250], char newpop[100][250], int popsize,
int lchrom, float *fit, float sum, float pcross, float pmu, int n)
{
int j,mate1,mate2;
j=0;
while(1)
{
mate1=select(fit,sum,popsize);
mate2=select(fit,sum,popsize);
crossover(oldpop[mate1],oldpop[mate2],newpop[j],newpop[j+1],lchrom,pcross,pmu,n);
j+=2;
if(j>=popsize) break;
}
}
/*ham giai ma*/
void decode(char *indi,int lchrom,float *up,float *down,double rate,float *k,int n)
{
int i,j;
double accum,power;
char frac[30];
for(j=0;j<n;j++)
{
for(i=0;i<lchrom;i++)
frac[i]=indi[j*lchrom+i];
power=1;
for(accum=0,i=0;i<lchrom;i++)
{
if(frac[i])
accum+=power;
power*=2;
}
power=accum/rate;
k[j]=down[j]+(up[j]-down[j])*power;
}
}
/*ham muc tieu*/
float f(float *k)
{
float s;
s=(k[0]-6)*(k[0]-6)+(k[1]-4)*(k[1]-4);
return s;
}
/*ham di truyen*/
float GEN(float *X,float *up,float *down,int gen,float ss(float *),
float pcross,float pmu,int n,int popsize)
{
char oldpop[100][250],newpop[100][250];
float obj[100],fit[100],sum,ty;
int lchrom,i,j,N;
float k[10],x[10];
double rate;
lchrom=250/n;
if(lchrom>25) lchrom=25;
N=lchrom*n;
sum=1;
for(rate=0,i=0;i<lchrom;i++)
{
rate+=sum;
sum*=2;
}
randomize();
ty=1.0e37;
initpop(oldpop,popsize,N);
for(j=0;j<gen;j++)
{
for(i=0;i<popsize;i++)
{
decode(oldpop[i],lchrom,up,down,rate,k,n);
obj[i]=ss(k);
if(ty>obj[i])
{
for(int l=0;l<n;l++)
X[l]=k[l];
ty=obj[i];
}
}
sum=scalepop(obj,fit,popsize);
generate(oldpop,newpop,popsize,lchrom,fit,sum,pcro ss,pmu,n);
reproduction(oldpop,newpop,popsize,N);
}
return ty;
}
/*ham chinh*/
int main()
{
float x[3],y;
float up[]={10,10};
float down[]={-10,-10};
y=GEN(x,up,down,50,f,.85,.05,2,40);
printf("\f_min=%6.4f\n",y);
for(int i=0;i<2;i++)
printf("x[%d]=%4.2f ",i+1,x[i]);
return 0;
}