⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ga.c.txt

📁 遗传算法的C语言源程序遗传算法的C语言源程序遗传算法的C语言源程序遗传算法的C语言源程序
💻 TXT
字号:
#include <math.h>
#include <iostream.h>
#include <iomanip.h>


/////////////////////////////////////////////////
//静态变量定义(产生随机数专用)
static int inextp,iff,inext;
static double ma[57];

//////////////////////////////////////////////////
struct individual             //定义个体
{
 unsigned   chrom[5];      //个体拥有的染色体
 double     fitness;       //个体适应度
 double     varible;   //个体对应的变量值
 int        xsite;     //交叉位置
    int        parent[1];     //父个体
 int        *utinity;      //特定数据指针变量
};

struct  bestever
{
 unsigned    chrom[5];     //最佳个体染色体
 double      fitness;      //最佳个体适应度
 double      varible;  //最佳个体对应的变量值
 int         generation;   //最佳个体生成代
};

/////////////////////////////////////////////////////////
struct  individual  oldpop[20];    //当前代种群
struct  individual  newpop[20];    //新一代种群

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     ncross;                //总交叉次数
int     nmutation;             //总变异次数
int     idum=-1;               //随机数系数
//////////////////////////////////////////////////////////////////
//函数定义
void     initpop();                         
double   ran3(int& idum);                
void     objfunc(struct individual *);          
int      select();                           
int      rnd(int low,int high); 
int      crossover(unsigned *parent1,unsigned *parent2,unsigned *child1,unsigned *child2);
void     mutation(unsigned *child);      //变异操作   
void     generation();                   //生成下一代 
void     sumfit();                       //种群适应度求和
void     statistics(struct individual *pop);   
/////////////////////////////////////////////////////////////////// 
void initialize()        //遗传算法初始化 
{
 //输入种群个体总数
    //cout<<"输入种群个体总数popsize(20~100)"<<"\n";
 //cin>>popsize;
    popsize=20;
 if(popsize%2!=0)
 {
  popsize++;
  cout<<"popsize已设为偶数";
 }

 //输入染色体长度
 //cout<<"输入染色体长度lchrom(8~40)";
 //cin>>lchrom;
    lchrom=78;
 //确定染色体的字节长度 
    chromsize = (lchrom/(8*sizeof(unsigned)));
    if(lchrom%(8*sizeof(unsigned))) 
 {
  chromsize++;
 }

 //输入最大世代数
 //cout<<"输入最大世代数maxgen(100~300)";
 //cin>>maxgen;
    maxgen=300;

 //输入交叉率和变异率
 //cout<<"输入交叉率pcross(0.2~0.9)";
 //cin>>pcross;
    pcross=0.8;

 //cout<<"输入变异率pmutation(0.01~0.1)";
 //cin>>pmutation;
    pmutation=0.05;

 //初始化全局计数变量和一些数值
    nmutation = 0;
    ncross = 0;
    bestfit.fitness = 0.0;
    bestfit.generation = 0;

 //初始化种群,并统计计算结果
    initpop();
}

void  initpop()          //随机化初始种群
{
 int        i,j,k=0,stop=0;
 unsigned int mask=1; 
 for(i=0;i<popsize;i++)         //个体染色体初始化
 {
  for(j=0;j<chromsize;j++)
  {
   oldpop[i].chrom[j]=0;
   if(j==(chromsize-1))
   {
    stop=lchrom-(j*(8*sizeof(unsigned)));
   }
   else
   {
    stop=8*sizeof(unsigned);
   }
   for(k=1;k<=stop;k++)
   {
    oldpop[i].chrom[j]=oldpop[i].chrom[j]<<1;
    if(ran3(idum)<=0.5)
    {
     oldpop[i].chrom[j]=oldpop[i].chrom[j]|mask;
    }
   }
  }
  oldpop[i].parent[0]=0;        //初始化父个体信息
  oldpop[i].parent[1]=0;
  oldpop[i].xsite=0;
  objfunc(&(oldpop[i]));        //计算个体适应度
 }
} 


/////////////////////////////////////////////////////////////
//计算适应度                       
void objfunc(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)));
  }
  else
  {
   stop=k*(8*sizeof(unsigned));
  }
  tp=critter->chrom[k];
  for(j=0;j<stop;j++)
  {
   bitpos=j+(8*sizeof(unsigned))*k;
   if((tp&mask)==1)
   {
    bitpow=powl(2.0,(double)bitpos);
    critter->varible=critter->varible+bitpow;
   }
   tp=tp>>1;
  }
 }
 critter->varible=-1+3*critter->varible/(powl(2.0,(double)lchrom)-1);
 critter->fitness=critter->varible*sin(critter->varible*10*atan(1)*4)+2.0;
}


int select()              //新个体选择程序
{
 double sum,pick;
 int i;
 pick=ran3(idum);
 sum=0;
 if(sumfitness!=0)
 {
  for(i=0;(sum<pick)&&(i<popsize);i++)
  {
   sum+=oldpop[i].fitness/sumfitness;
  }
 }
 else
 {
  i=int(ran3(idum)*double(popsize));
 }
 return(i-1);
}


//由两个父个体产生两个子个体
int crossover(unsigned *parent1,unsigned *parent2,unsigned *child1,unsigned *child2)
{
 int j,k;
 unsigned jcross;
 unsigned mask,temp;
 if(ran3(idum)<=pcross)         //产生随机数小于交叉率时执行交叉操作
 {
  jcross=rnd(1,lchrom-1); //交叉位置在1~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<=(int)(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 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)));
  }
  else
  {
   stop=8*sizeof(unsigned);
  }
  for(j=0;j<stop;j++)
  {
   if(ran3(idum)<=pmutation)
   {
    mask=mask|(temp<<j);
    nmutation++;
    child[k]=(child[k])^(mask);
   } 
  }  
 }
}

void generation()
{
 int mate1,mate2,jcross,j=0;
 sumfit();
 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 sumfit()
{
 int j=0;
 sumfitness=0;
 for(j=0;j<popsize;j++)
 {
  sumfitness=sumfitness+oldpop[j].fitness;
 }
}

void main()  //主程序
{ 
 struct individual temp[20];
 //cout<<"输入遗传算法执行次数(1~5)"<<endl;
 //cin>>maxruns;
    maxruns=10;
 max=0;
 for(run=1;run<=maxruns;run++)
 {
  initialize();
  for(gen=0;gen<maxgen;gen++)
  {
   generation();
   for(int i=0;i<20;i++)
   {
    temp[i]=oldpop[i];
       oldpop[i]=newpop[i];
       newpop[i]=temp[i];
       if(max<oldpop[i].fitness)
    {
                    max=oldpop[i].fitness;     
    }
   }
  }
 }
 for(int i=0;i<20;i++)
 {       
      cout<<oldpop[i].fitness<<"\n";
 }
 cout<<"max="<<max<<"\n";
}


/////随机数生成器////////////////////////

double ran3(int& idum)
{
 double mk,b,fac,mj;
 int i,ii,k,mbig,mz;
 long mseed;
 mbig =1000000000;
 mseed=161803398;
 mz=0;
 fac=0.000000001;
 if((idum<0)||(iff==0))
 {
  iff=1;
  mj=mseed-fabs(idum);
  mj=mj-mbig*int(mj/mbig);
  ma[56]=mj;
  mk=1;
  for(i=1;i<=54;i++)
  {
   ii=(21*i)-55*int((21.0*i)/55.0);
   ma[ii]=mk;
   mk=mj-mk;
   if(mk<mz)
   {
    mk=mk+mbig;
    mj=ma[ii];
   }
  }
  for(k=1;k<=4;k++)
  {
   for(i=1;i<=55;i++)
   {
    ma[i]=ma[i]-ma[1+i+30-55*int((i+30)/55)];
    if(ma[i]<mz)
    {
     ma[i]=ma[i]+mbig;
    }
   }
  }
  inext=0;
  inextp=31;
  idum=1;
 }
 inext=inext+1;
 if(inext==56)
 {
  inext=1; 
 }
 inextp=inextp+1;
 if(inextp==56)
 {
  inextp=1;
 }
 mj=ma[inext]-ma[inextp];
 if(mj<mz)
 {
  mj=mj+mbig;
 }
 ma[inext]=mj;
 b=mj*fac;
 return b;
}

int rnd(int low,int high)
{
 int i;
 double temp;
 temp=ran3(idum);
 i=(int)temp*(high-low+1);
    if(i<low)
 {
  i=low;
 }
 if(i>high)
 {
  i=high;
 }
 return i;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -