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

📄 myga_2.c

📁 遗传算法解决双变量的函数最优化问题
💻 C
📖 第 1 页 / 共 2 页
字号:

//*******************************个体变异*****************************
void peoplemutate(struct pp *pp1,int k)
{
  int i;
  randomize();
  i=random(lchrom);
  if(flip(0))
  { if(pp1[k].chromX[i])
	pp1[k].chromX[i]=0;
  }
  i=random(lchrom);
  if(flip(0))
  { if(pp1[k].chromY[i])
        pp1[k].chromY[i]=0;
  }
}


//****************************产生下一代种群*******************************
void generation()                  //产生下一代种群
{ unsigned int j,mate1,mate2;
  int flag=1;                               //交叉或竞争的标志
  j=0;
  do
  {mate1=select();                    //找出两个体进行交叉竞争
   mate2=select();
   //以某种概率留部分顶级种群
   flag=crossover_compete(oldpop[mate1].chromX,oldpop[mate2].chromX,oldpop[mate1].chromY,oldpop[mate2].chromY,j);
   if(flag)
   {
   peoplemutate(newpop,j);
   peoplemutate(newpop,j+1);
   newpop[j].x=(float)decode(newpop[j].chromX,Xmin,Xmax);
   newpop[j].y=(float)decode(newpop[j].chromY,Ymin,Ymax);
   newpop[j].fitness=objfitness(newpop[j].x,newpop[j].y);
   newpop[j].parent1=mate1;
   newpop[j].parent2=mate2;
   newpop[j].xsite=jcross;
   newpop[j+1].x=(float)decode(newpop[j+1].chromX,Xmin,Xmax);
   newpop[j+1].y=(float)decode(newpop[j+1].chromY,Ymin,Ymax);
   newpop[j+1].fitness=objfitness(newpop[j+1].x,newpop[j+1].y);
   newpop[j+1].parent1=mate1;
   newpop[j+1].parent2=mate2;
   newpop[j+1].xsite=jcross;
   j=j+2;
   }
   else                                 //以一定的概率两两竞争,留下一个个体
   {
     if(oldpop[mate1].fitness<oldpop[mate2].fitness)
     newpop[j]=oldpop[mate2];
     else
     newpop[j]=oldpop[mate1];
     peoplemutate(newpop,j);
     j=j+1;
   }
  }while (j<popsize);
  newpop[popsize-1]=oldpop[popsize-1];  //直接继承最大适应度值的个体
}

//**********************************对种群进行选择***************************************


int select()                      //对种群进行选择,选出两个个体进行交叉或竞争或和谐共处
{                                       //用改进的轮转赌轮法
  double rand1,partsum;
  int j;
  float a,b,pgen;     
   pgen=(float)(1.0*gen/maxgen);                       //进行适应度调整的两参数
  partsum=0.0;
  j=0;
  rand1=random1()*sumfitness;
  if (pgen<=0.3)                  //对不同时期的种群进行不同的适应度调整
  {a=0.1; b=0.9*avgfitness;}
  else if(0.3<pgen<=0.7)
  {a=1;b=0;}
  else
  {
   a=2;b=-1*avgfitness;
   if ((a*min+b)<=0)
    {a=1;b=0;}
  }
  while(((a*partsum+b)<rand1)&&(j<popsize))
  {
    partsum=partsum+oldpop[j].fitness;
    j=j+1;
  }
  return j-1;
}


int flip(float probability)          //对某概率的样本进行随机的选取,选到返回1,否则返回0
{
 float ppp;
 ppp=random(20001)/20000.0;
 if(ppp<=probability) return 1;
 return 0;
}

//*********************************求个体的适应度***************************************

double objfitness(float x1,float x2)   //求个体的适应度
{ float y;
  y=100*(x1*x1-x2)*(x1*x1-x2)+(1-x1)*(1-x1);
  return y;
}

//********************************对种群进行统计*****************************************

void statistics(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;
    }
  }
 avgfitness=sumfitness/(float)popsize; /*求出平均适应度值*/

}

//**************************求当前的交叉概率*******************************


float now_pcross()             //求当前的交叉概率
{
 float p,pgen;
 pgen=(float)(gen*1.0/maxgen);
 if(pgen<=0.3)
 p=pcross;
 else if(0.3<pgen<=0.6)
 p=pcross;
 else if(0.6<pgen<=0.95)
 p=0.8;
 else
 p=0.5;
 return p;
}


//****************************求当前的变异概率********************************

float now_pmutation()          //求当前的变异概率
{
 float p,pgen;
 pgen=(float)(gen*1.0/maxgen);//注意这里要乘以1.0 用来化为float型!!!!!!!!!重要!!!!!!!!
 if(pgen<=0.2)
 p=0.4;
 else if(0.2<pgen<=0.3)
 p=pmutation;
 else if(0.3<pgen<=0.8)
 p=0.3;
 else if(0.5<pgen<=0.8)
 p=pmutation;
 else
 p=0.01;
 return p;
}

//**************************************解码操作**********************************************
double decode(unsigned char *pp,float xmin,float xmax) //把值定义在一个区间内的二进制数转化为十进制数,即解码操作
{
 int j;
 double power;//各位的权重
 double value;
 power=1.0;
 value=0.0;
 for(j=lchrom-1;j>-1;j--)//十进制变二进制
 { if(pp[j]) value=value+power;
   power=2.0*power;
 }
 value=(value/(pow(2,lchrom)-1))*(xmax-xmin)+xmin;
//把二进制值映射到[xmin,xmax]区间上
 return value;
}

float random1()
{
 jrand=jrand+1;
 if (jrand>=lchrom)
  {jrand=0;
   randomize1();
  }
 return oldrand[jrand];
}


void randomize1()                    /*randomize again*/
 {
  int i;
  randomize();
  for(i=0;i<lchrom;i++)
    oldrand[i]=random(30001)/30000.0;
  jrand=0;
 }

void initpop()                       //初始化种群
{
 int j,j1;
 for(j=0;j<popsize;j++)
  { randomize();
    for (j1=0;j1<lchrom;j1++)
   { 
    oldpop[j].chromX[j1]=(int)(random(20000)/10000.0);     /*随机产生由0/1组成的染色体*/
    oldpop[j].chromY[j1]=(int)(random(20000)/10000.0); ;     /*随机产生由0/1组成的染色体*/
   }
   oldpop[j].x=(float)decode(oldpop[j].chromX,Xmin,Xmax);
   oldpop[j].y=(float)decode(oldpop[j].chromY,Ymin,Ymax);
   oldpop[j].fitness=objfitness(oldpop[j].x,oldpop[j].y);
   oldpop[j].parent1=0;
   oldpop[j].parent2=0;
   oldpop[j].xsite=0;
  }
}



void pause()                            /*pause*/
{
 int j,j1;
 int x1;
 x1=0;
 for(j=1;j<=25;j++)
 for (j1=1;j1<2;j1++) x1=x1+1;
}


void CoBox(int x,int y,int l,int h,int color)
{
  setfillstyle(1,8);
  bar(x,y,x+l,y+h);
  setfillstyle(1,color);
  bar(x+2,y+2,x+l-2,y+h-2);
  setcolor(15);
  line(x,y,x+l,y);
  line(x,y,x,y+h);
  line(x+1,y+1,x+l-1,y+1);
  line(x+1,y+1,x+1,y+h-1);
}



void CoReBox(int x,int y,int l,int h,int color)
{
  setfillstyle(1,8);
  bar(x,y,x+l,y+h);
  setfillstyle(1,color);
  bar(x+2,y+2,x+l-2,y+h-2);
  setcolor(15);
  line(x,y+h,x+l,y+h);
  line(x+l,y+h,x+l,y);
  line(x+1,y+h-1,x+l-1,y+h-1);
  line(x+l-1,y+h-1,x+l-1,y+1);
}



void clearscreen()
{
  setfillstyle(1,15);
  bar(330,50,630,250);
  setlinestyle(0,0,3);
  setcolor(4);
  line(325,250,630,250);
  line(630,250,620,240);
  line(630,250,620,260);
  line(330,255,330,45);
  line(330,45,320,55);
  line(330,45,340,55);
  setfillstyle(1,15);
  bar(375,265,585,475);
  setcolor(4);
  setlinestyle(0,0,3);
  rectangle(375,265,585,475);
}


void drawgraph(int gen,float oldmax)
{
  int Gx,Gy,Gx1,Gy1;
  int Px,Py;
  int j;
  Gy=(int)(max*200/4000);
  Gx=(int)(gen*300.0/maxgen);
  Gy1=(int)(oldmax*200/4000);
  Gx1=(int)((gen-1)*300.0/maxgen);

  setlinestyle(0,0,1);
  setcolor(2);
  line(330+Gx1,250-Gy1,330+Gx,250-Gy);
  for (j=0;j<popsize;j++)
  {
   Px=(int)(newpop[j].x*50+480);
   Py=(int)(370-newpop[j].y*50);
   line(Px-3,Py,Px+3,Py);
   line(Px,Py-3,Px,Py+3);
  }

}

void resetmenu()
{
  setcolor(9);
  settextstyle(0,0,1);
  CoBox(20,80+80,120,30,10);
  outtextxy(20,80+10+80," 1 SET");
  CoBox(20,170+40,120,30,10);
  outtextxy(20,170+10+40,"2 RESET");
  CoBox(180,80+80,120,30,10);
  outtextxy(180,80+10+80," 3 START");
  CoBox(180,170+40,120,30,10);
  outtextxy(180,170+10+40," 4 EXIT");
}





void report()
{
   int k;
   setfillstyle(1,0);
   bar(0,0,getmaxx(),100);
   gotoxy(10,1);
   printf("Population Report\n");
   for(k=0;k<79;k++) printf("*");
   printf("\n");
   printf("RESULT: ");
   printf("avgfitness=%8.4f  MIN=%8.4f  MAX=%8.4f\n",avgfitness,min,max);
   printf("x=%8.4f  y=%8.4f  \n",oldpop[maxpp].x,oldpop[maxpp].y);
   printf("         ncross=%d   nmutation=%d\n",ncross,nmutation);
   free(p1);
   free(oldpop);
   free(newpop);

}

⌨️ 快捷键说明

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