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

📄 jqa.c

📁 这是一个遗传算法的C代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include<stdio.h>
#include<stdlib.h>
#include<graphics.h>
#include<math.h>
#include<time.h>
#include<string.h>
#include "graph.c"
/* 宏定义 */
#define TL1      20          /* 植物性食物限制时间 */
#define TL2      5           /* 动物性食物限制时间 */
#define NEWFOODS 3           /* 植物性食物每代生成数目  */
#define MUTATION 0.05        /* 变异概率     */
#define G_LENGTH  32         /* 个体染色体长度  */
#define MAX_POP  100         /* 个体总数的最大值  */
#define MAX_FOOD 100         /* 食物总数的最大值  */
#define MAX_WX    60         /* 虚拟环境的长度最大值 */
#define MAX_WY    32         /* 虚拟环境的宽度最大值 */
#define SX1      330         /* 虚拟环境图左上角点x坐标  */
#define SY1      40          /* 虚拟环境图左上角点y坐标  */
#define GX       360         /* 个体数进化图形窗口的左上角点X坐标  */
#define GY       257         /* 个体数进化图形窗口的左上角点Y坐标  */
#define GXR      250         /* 个体数进化图形窗口的长度    */
#define GYR      100         /* 个体数进化图形窗口的宽度    */
#define GSTEP     2          /* 个体数进化图形窗口的X方向步长    */
#define R_LIFE  0.05         /* 初期产生生物数的环境比率 */
#define R_FOOD  0.02         /* 初期产生食物数的环境比率 */
#define SL_MIN    10         /* 个体寿命最小值   */
/* 全局变量 */
unsigned  char  gene[MAX_POP][G_LENGTH];     /* 遗传基因      */
unsigned  char  iflg[MAX_POP];               /* 个体死活状态标志变量  */
unsigned  char  fflg[MAX_FOOD];              /* 食物有无状态标志变量  */
unsigned  char  world[MAX_WX][MAX_WY];       /* 虚拟环境的数据    */
unsigned char                                /* 各中行为模式数据 */
life1[5][5]={{0,0,1,0,0},{0,1,0,1,0},{1,0,0,0,1},{0,1,0,1,0},{0,0,1,0,0}};
unsigned char
life2[5][5]={{1,1,1,1,1},{1,0,0,0,1},{1,0,0,0,1},{1,0,0,0,1},{1,1,1,1,1}};
unsigned char
food1[5][5]={{0,0,0,1,0},{0,0,1,1,0},{0,1,0,1,0},{0,0,1,1,0},{0,0,0,1,0}};
unsigned char
food2[5][5]={{0,0,0,1,0},{0,0,1,1,0},{0,1,1,1,0},{0,0,1,1,0},{0,0,0,1,0}};
int pop_size;                   /* 个体总数   */
int iatr[MAX_POP][4];           /* 个体属性   */
                                /* iatr[][0]  个体当前位置x坐标  */
                                /* iatr[][1]  个体当前位置y坐标  */
                                /* iatr[][2]  内部能量  */
                                /* iatr[][3]  年龄属性  */
int food_size;                  /* 食物总数  */
int fatr[MAX_FOOD][4];          /* 食物属性  */
                                /* fatr[][0]  食物当前位置x坐标  */
                                /* fatr[][1]  食物当前位置y坐标  */
                                /* fatr[][2]=0 : 植物性 =1:动物性 */
                                /* fatr[][3]  新鲜程度    */
int wx,wy;                      /* 虚拟环境的长宽度  */

void uni_crossover(gene,g1,g2,g3,ratio1,g_length)    /* 均匀交叉 */
unsigned char *gene;                                 /* 遗传基因 */
int g1,g2,g3;                                        /* g1 g2 父个体编号  g3 子个体编号  */
double ratio1;                                       /*  父个体g1被选中的概率  */
int g_length;                                        /* 个体遗传基因的位长  */
{
   unsigned char *gene1;        /*  父1遗传基因的指针 */
   unsigned char *gene2;        /*  父2遗传基因的指针 */
   unsigned char *gene3;        /*  子遗传基因的指针 */
   double rnd,r1;
   int i;
   gene1=gene+g_length*g1;
   gene2=gene+g_length*g2;
   gene3=gene+g_length*g3;
   r1=(int)(10000.0*ratio1);
   for(i=0;i<g_length;i++)
   {  rnd=random(10000);
      if(rnd<=r1)    *(gene3+i)=*(gene1+i);
      else           *(gene3+i)=*(gene2+i);
   }
}

void g_disp_unit(x,y,n) 
/* 绘制虚拟环境的一个单元  */
int x,y;        /* x=0,1,2....,wx-1;   y=0,1,2,....,wy-1  */
int n;          /* n=0: =1: 生物1  =2:生物2   =3:植物性食物  =4:障碍物  =5:动物性食物 */
{
   int gx,gy,i,j;
   unsigned char col;
   gx=SX1+5*x;gy=SY1+5*y;
   for(i=0;i<5;i++)
     for(j=0;j<5;j++)
     {  switch(n)
   { case 0: col=0;             break;
     case 1: col=life1[j]  [ i]*2; break;
     case 2: col=life2[j]  [ i]*4; break;
     case 3: col=food1[j]  [ i]*6; break;
     case 4: col=7;             break;
     case 5: col=food2[j]  [ i]*11;
    }
  g_pset(gx+j,gy+i,col);
       }
   }

void g_draw_world()         /* 显示虚拟环境画面  */
{
int i,j;
for(i=0;i<wy;i++)
  for(j=0;j<wx;j++)
  g_disp_unit(j,i,world[j] [ i]);
}

void g_draw_frame(x1,y1,x2,y2,c1,c2,c3,c4,text)
int x1,y1,x2,y2,c1,c2,c3,c4;
char *text;
{  int n,x3;
   g_rectangle(x1,y1,x2,y2,c1,1);
   g_rectangle(x1,y1,x2,y2,c2,0);
   g_rectangle(x1,y1,x2,y1+16,c3,1);
   g_rectangle(x1,y1,x2,y1+16,c2,0);
   n=strlen(text);
   x3=x1+((x2-x1-n*8)/2);
   disp_hz16(text,x3,y1,c4);
}

void g_init_frames()      /*  初始化画面  */
{
  int i,j,cx,cy,x,y;
  char text[17];
  g_draw_frame(0,0,639,399,15,0,4,15,
      "基于遗传算法的人工生命模拟");
  g_draw_frame(0,16,320,170,7,0,8,15,"设定参数");
  y=48;
   setcolor(9);
  disp_hz16("植物食物限制时间",16,y,15);
  sprintf(text,"%d",TL1);
  g_text(200,y+8,4,text);
  y=y+24;
   setcolor(9);
  disp_hz16("动物食物限制时间",16,y,15);
  sprintf(text,"%d",TL2);
  g_text(200,y+8,4,text);
  y=y+24;
   setcolor(9);
  disp_hz16("植物食物每代生成个数",16,y,15);
  sprintf(text,"%d",NEWFOODS);
  g_text(200,y+8,4,text);
  y=y+24;
   setcolor(9);
  disp_hz16("变异概率",16,y,15);
  i=(int)(MUTATION*100.0);
  sprintf(text,"%d",i);
  g_text(152,y+8,4,text);
  g_draw_frame(0,170,320,399,7,0,8,15,"最佳基因型");
  x=16;y=194;
   setcolor(9);
  disp_hz16("SP:物种号........",x,y,15);y=y+16;
  disp_hz16("SL:寿命..........",x,y,15);y=y+16;
  disp_hz16("VF:视野..........",x,y,15);y=y+16;
  disp_hz16("TM:基本移动模式..",x,y,15);y=y+16;
  disp_hz16("CM:移动特点......",x,y,15);y=y+16;
  disp_hz16("LM:移动能耗......",x,y,15);y=y+16;
  disp_hz16("CA:行动特点......",x,y,15);y=y+16;
  disp_hz16("CR:善变性........",x,y,15);y=y+16;
  disp_hz16("SA:攻击速度......",x,y,15);y=y+16;
  disp_hz16("DA:防御能力......",x,y,15);y=y+16;
  disp_hz16("LA:攻击能耗......",x,y,15);y=y+16;
  disp_hz16("EF:食物吸取效率..",x,y,15);y=y+16;
  g_draw_frame(320,16,639,207,7,0,8,15,"虚拟世界");
  g_draw_frame(320,207,639,399,7,0,8,15,"世代个体数目变化");
  }

void g_init_graph() 
/*  个体数进化图初始化  */
{
   g_rectangle(GX,GY,GX+GXR,GY+GYR,0,1);
   g_rectangle(GX,GY,GX+GXR,GY+GYR,6,0);
   setcolor(1);
   disp_hz16( "生物 1",GX+5,GY-18,15);
   g_line(GX+90,GY-10,GX+110,GY-10,1);
   setcolor(4);
   disp_hz16( "生物 2",GX+120,GY-18,15);
   g_line(GX+205,GY-10,GX+225,GY-10,4);
   setcolor(0);
   disp_hz16("世代数",GX+168,GY+GYR+10,15);
   g_text(GX-25,GY,0,"100");
   g_text(GX-14,GY+GYR,0,"0");
}

void g_plot_population(gen_num,n1,n2,n1old,n2old)
int gen_num,n1,n2,n1old,n2old;
{
  int x,y,gx,gy,x_old,y_old;
  char text[8];
  if(gen_num%10==0)
  {
     x=GX+(gen_num-1)*GSTEP;
     g_line(x,GY+1,x,GY+GYR-1,1);
     sprintf(text,"%d",gen_num);
     if(gen_num<100||gen_num%20==0)
      g_text(x-8,GY+GYR+5,15,text);
  }
  x_old=GX+(gen_num-1)*GSTEP;
  x=x_old+GSTEP;
  y_old=GY+GYR-n1old;
  y=GY+GYR-n1;
  g_line(x_old,y_old,x,y,1);
  y_old=GY+GYR-n2old;
  y=GY+GYR-n2;
  g_line(x_old,y_old,x,y,4);
}

void g_disp_genotype()             /* 显示最佳个体的遗传基因型  */
{
  int i,j,n0,n1,x,y;
  unsigned char g[G_LENGTH];
  unsigned char bits[12][2]=
  { {0,0},{1,4},{5,6},{7,8},{9,11},{12,12},{13,15},
    {16,18},{19,21},{22,24},{25,27},{28,31}};
   /*  画面消除  */
   g_rectangle(200,187,319,398,7,1);
    if(pop_size!=0)
    {
     /* 获取各遗传因子 */
      for(i=0;i<G_LENGTH;i++)
      {
n0=0;n1=0;
for(j=0;j<pop_size;j++)
  if(gene[j] [ i]==0) n0++;
  else  n1++;
  if(n0>=n1) g [ i]=0; else g [ i]=1;
      }
      x=220;
      for(i=0;i<12;i++)
      {
y=202+i*16;
for(j=bits [ i][0];j<=bits [ i][1];j++)
if(g[j]==0)
   g_text(x+(j-bits [ i][0])*16,y,4,"0");
   else
   g_text(x+(j-bits [ i][0])*16,y,4,"1");
   }
      }
  }

void g_disp_char(x,y,x1,y1,x2,y2,v) 
int x,y,x1,y1,x2,y2;
unsigned char v;
{
   char c[10];
   if(x>=x1&& x<=x2-8 && y>=y1 && y<=y2-10)
   {
   switch(v)
    {
case 0: strcpy(c,"0\0");break;
case 1: strcpy(c,"+\0");break;
case 2: strcpy(c,"-\0");break;
case 3: strcpy(c,"x\0");
   }
   g_text(x,y,15,c);
   }
}
void remove_life(n)               /* 消除第n个个体  */
int n;
{
  iflg[n]=0;
  world[iatr[n][0]][iatr[n][1]]=0;
  g_disp_unit(iatr[n][0],iatr[n][1],0);
  if(food_size+1<=MAX_FOOD)
  {
  food_size++;
  fatr[food_size-1][0]=iatr[n][0];
  fatr[food_size-1][1]=iatr[n][1];
  fatr[food_size-1][2]=1;
  fatr[food_size-1][3]=0;
  fflg[food_size-1]=1;
  world[iatr[n][0]][iatr[n][1]]=5;
  g_disp_unit(iatr[n][0],iatr[n][1],5);
  }
}

void  remove_food(n)              /* 消除第n个食物 */
int n;
{
  fflg[n]=0;
  world[fatr[n][0]][fatr[n][1]]=0;
  g_disp_unit(fatr[n][0],fatr[n][1],0);
  }

void make_lives_and_foods()         /* 设置虚拟环境中生物与食物  */
{
  int x,y,i,j;
  pop_size=0;
  food_size=0;
  for(y=0;y<wy;y++)
    for(x=0;x<wx;x++)
    {
      if(world[x][y]==1||world[x][y]==2)
      {
       if(pop_size+1<=MAX_POP)
       {
  pop_size++;
/* 生成遗传因子 */
           gene[pop_size-1][0]=world[x][y]-1;
    for(i=1;i<G_LENGTH;i++)
      gene[pop_size-1] [ i]=random(2);
           /*  设定属性  */
     iatr[pop_size-1][0]=x;
     iatr[pop_size-1][1]=y;
     iatr[pop_size-1][2]=70+random(30);
     iatr[pop_size-1][3]=random(SL_MIN);
     }
       }
       if(world[x][y]==3||world[x][y]==5)
       {
  if(food_size+1<=MAX_FOOD)
  {
  food_size++;
         /* 设定属性  */
  fatr[food_size-1][0]=x;
  fatr[food_size-1][1]=y;
  if(world[x][y]==3)
       fatr[food_size-1][2]=0;
  else
       fatr[food_size-1][2]=1;
fatr[food_size-1][3]=random(TL1-1)+1;
}
      }
    }
}

void find_empty(x,y)              /* 寻找虚拟环境中的空处,返回坐标  */
  int *x,*y;
  {
  int ok;
  ok=0;
  while(ok==0)
  {
   *x=random(wx);*y=random(wy);
   if(world[*x][*y]==0) ok=1;
   }
  }

void make_world()                 /* 随机设定人工环境  */
{
int i,j,k,num,x,y;
int ok,overlap;
char choice[3];
double size;
wx=0;
while(wx<10||wx>MAX_WX)
{
     setcolor(15);
     disp_hz16("虚拟环境长度(10-60)",10,210,20);
     gscanf(300,210,4,0,3,"%s",choice);
     wx=atoi(choice);
  }
wy=0;
while(wy<10||wy>MAX_WY)
{
     setcolor(15);
     disp_hz16("虚拟环境宽度(10-32)",10,240,20);
     gscanf(300,240,4,0,3,"%s",choice);
     wy=atoi(choice);
  }
for(i=0;i<wy;i++)
  for(j=0;j<wx;j++)
   if(i==0||i==wy-1||j==0||j==wx-1)
    world[j] [ i]=4;
    else    world[j] [ i]=0;
/* 设定障碍物  */
size=(double)(wx*wy);
num=(int)(size/40.0);
if(num>MAX_POP)  num=MAX_POP;
for(i=0;i<num;i++)
{
   find_empty(&x,&y);
   world[x][y]=4;
   }
num=(int)(size/5.0);
if(num>MAX_FOOD) num=MAX_FOOD;
for(i=0;i<num;i++)
{
ok=0;
while(ok==0)
{
    x=random(wx);y=random(wy);
    if((world[x][y]!=4) &&
       (world[x][y-1]==4 || world[x][y+1]==4 ||
        world[x-1][y]==4 || world[x+1][y]==4))
{  world[x][y]=4;
    ok=1;
    }
    }
}

  for(y=0;y<wy;y++)
  for(x=0;x<wx;x++)
    if(world[x][y]==0)
    {
    num=0;
    for(i=-1;i<=1;i++)
     for(j=-1;j<=1;j++)
       if(get_world(x+j,y+i)==4)
       num++;
       if(num>=6) world[x][y]=4;
       }
  /*  设定生物  */
  num=(int)(size*R_LIFE);
  for(i=0;i<num;i++)
  {  find_empty(&x,&y);
     world[x][y]=random(2)+1;
     }
  /* 设定食物  */
  num=(int)(size*R_FOOD);
  for(i=0;i<num;i++)
     {
     find_empty(&x,&y);
     world[x][y]=3;
}
}

void load_world_file()         /* 读取虚拟环境数据文件设定  */
{
FILE *fopen(),*fpt;
char st[100],c;
int i,j;
if((fpt=fopen("\\ga\\world","r"))==NULL) exit(-1);
else
{
   fscanf(fpt,"%d",&wx);
   fscanf(fpt,"%d",&wy);
   for(i=0;i<wy;i++)
    for(j=0;j<wx;j++)
    fscanf(fpt,"%d",&world[j] [ i]);
    fclose(fpt);
    }
}

int get_world(x,y)             /*坐标(x,y)处环境值  */
int x,y;
{
   if(x>=0 && x<wx && y>=0 && y<wy)
   return(world[x][y]);
  else
  return(-1);
}

int  decode_gene(n,sb,bw)               /* 第n个个体基因型解码  */
int  n,sb,bw;                           /*  sb开始位  bw位长 */
{
  int i,sum;
  sum=0;
  for(i=sb;i<sb+bw;i++)
  sum=sum*2+gene[n] [ i];
  return(sum);
  }

void  move_pos(n,x1,y1,x2,y2)          /* 个体n从(x1,y1)移动到(x2,y2)   */
int n,x1,y1,x2,y2;
{
  int sp,loss;
  loss=decode_gene(n,12,1)+1;          /* 移动消耗 */
  iatr[n][2]=iatr[n][2]-loss;          /*  内部能量更新 */
  if(iatr[n][2]<=0)  remove_life(n);
  else
  {
    /* 个体属性更新 */
    iatr[n][0]=x2;iatr[n][1]=y2;       /* x,y坐标更新 */
    /* 显示更新 */
    sp=gene[n][0]+1;
    g_disp_unit(x1,y1,0);              /*  当前位置(x,y)图形消除 */
    world[x1][y1]=0;
    g_disp_unit(x2,y2,sp);             /*  新位置图形表示 */
    world[x2][y2]=sp;
  }
}

void  move_randomly(n)                /*  个体n按照移动模式随机移动 */
int n;
{
  
/* 基本移动模式1  */
int  pat1[8][2]={{1,0},{1,1},{0,1},{-1,1},
    {-1,0},{-1,-1},{0,-1},{1,-1}};
  /* 基本移动模式2与3  */
int pat2_3[2][4][2]={{{1,0},{0,1},{-1,0},{0,-1}},
    {{1,1},{-1,1},{-1,-1},{1,-1}}};
int pat,x1,y1,x2,y2,rndnum;
pat=decode_gene(n,7,2);

⌨️ 快捷键说明

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