sga.c
上传用户:helpmateqq
上传日期:2013-03-23
资源大小:86k
文件大小:18k
开发平台:

Visual C++

  1. /********************************************************************/
  2. /*             基于基本遗传算法的函数最优化   SGA.C                 */
  3. /*     A Function Optimizer using Simple Genetic Algorithm          */
  4. /* developed from the Pascal SGA code presented by David E.Goldberg */
  5. /*              华南理工大学电子与信息学院   苏勇          2004年4月*/
  6. /********************************************************************/
  7. #include <stdio.h>
  8. #include <math.h>
  9. /* 全局变量 */
  10. struct individual                       /* 个体*/
  11. {
  12.     unsigned *chrom;                    /* 染色体 */
  13.     double   fitness;                   /* 个体适应度*/
  14.     double   varible;                   /* 个体对应的变量值*/   
  15.     int      xsite;                     /* 交叉位置 */
  16.     int      parent[2];                 /* 父个体  */
  17.     int      *utility;                  /* 特定数据指针变量 */
  18. };
  19. struct bestever                         /* 最佳个体*/
  20. {
  21.     unsigned *chrom;                    /* 最佳个体染色体*/
  22.     double   fitness;                   /* 最佳个体适应度 */
  23.     double   varible;                   /* 最佳个体对应的变量值 */
  24.     int      generation;                /* 最佳个体生成代 */
  25. };
  26.  struct individual *oldpop;             /* 当前代种群 */
  27.  struct individual *newpop;             /* 新一代种群 */
  28.  struct bestever bestfit;               /* 最佳个体 */
  29.  double sumfitness;                     /* 种群中个体适应度累计 */
  30.  double max;                            /* 种群中个体最大适应度 */
  31.  double avg;                            /* 种群中个体平均适应度 */
  32.  double min;                            /* 种群中个体最小适应度 */
  33.  float  pcross;                         /* 交叉概率 */
  34.  float  pmutation;                      /* 变异概率 */
  35.  int    popsize;                        /* 种群大小  */
  36.  int    lchrom;                         /* 染色体长度*/
  37.  int    chromsize;                      /* 存储一染色体所需字节数 */
  38.  int    gen;                            /* 当前世代数 */
  39.  int    maxgen;                         /* 最大世代数   */
  40.  int    run;                            /* 当前运行次数 */
  41.  int    maxruns;                        /* 总运行次数   */
  42.  int    printstrings;                   /* 输出染色体编码的判断,0 -- 不输出, 1 -- 输出 */
  43.  int    nmutation;                      /* 当前代变异发生次数 */
  44.  int    ncross;                         /* 当前代交叉发生次数 */
  45. /* 随机数发生器使用的静态变量 */
  46. static double oldrand[55];
  47. static int jrand;
  48. static double rndx2;
  49. static int rndcalcflag;
  50. /* 输出文件指针 */
  51. FILE *outfp ;
  52. /* 函数定义 */
  53. void advance_random();
  54. int flip(float);rnd(int, int);
  55. void randomize();
  56. double randomnormaldeviate();
  57. float randomperc(),rndreal(float,float);
  58. void warmup_random(float);
  59. void initialize(),initdata(),initpop();
  60. void initreport(),generation(),initmalloc();
  61. void freeall(),nomemory(char *),report();
  62. void writepop(),writechrom(unsigned *);
  63. void preselect();
  64. void statistics(struct individual *);
  65. void title(),repchar (FILE *,char *,int);
  66. void skip(FILE *,int);
  67. int select();
  68. void objfunc(struct individual *);
  69. int crossover (unsigned *, unsigned *, unsigned *, unsigned *);
  70. void mutation(unsigned *);
  71. void initialize()      /* 遗传算法初始化 */
  72. {
  73.     /* 键盘输入遗传算法参数 */
  74.     initdata();
  75.     /* 确定染色体的字节长度 */
  76.     chromsize = (lchrom/(8*sizeof(unsigned)));
  77.     if(lchrom%(8*sizeof(unsigned))) chromsize++;
  78.     /*分配给全局数据结构空间 */
  79.     initmalloc();
  80.     /* 初始化随机数发生器 */
  81.     randomize();
  82.     /* 初始化全局计数变量和一些数值*/
  83.     nmutation = 0;
  84.     ncross = 0;
  85.     bestfit.fitness = 0.0;
  86.     bestfit.generation = 0;
  87.     /* 初始化种群,并统计计算结果 */
  88.     initpop();
  89.     statistics(oldpop);
  90.     initreport();
  91. }
  92. void initdata()           /* 遗传算法参数输入 */
  93. {
  94.    char  answer[2];
  95.    popsize=30;
  96.    if((popsize%2) != 0)
  97.    {
  98. fprintf(outfp, "种群大小已设置为偶数n");
  99. popsize++;
  100.    };
  101.    lchrom=22;
  102.    printstrings=1;
  103.    maxgen=150;
  104.    pcross=0.8;
  105.    pmutation=0.005;
  106. }
  107. void initpop()           /* 随机初始化种群 */
  108. {
  109.     int j, j1, k, stop;
  110.     unsigned mask = 1;
  111.     for(j = 0; j < popsize; j++)
  112.     {
  113.         for(k = 0; k < chromsize; k++)
  114.         {
  115.             oldpop[j].chrom[k] = 0;
  116.             if(k == (chromsize-1))
  117.                 stop = lchrom - (k*(8*sizeof(unsigned)));
  118.             else
  119.                 stop =8*sizeof(unsigned);
  120.             for(j1 = 1; j1 <= stop; j1++)
  121.             {
  122.                oldpop[j].chrom[k] = oldpop[j].chrom[k]<<1;
  123.                if(flip(0.5))
  124.                   oldpop[j].chrom[k] = oldpop[j].chrom[k]|mask;
  125.             }
  126.         }
  127.         oldpop[j].parent[0] = 0;     /* 初始父个体信息 */
  128.         oldpop[j].parent[1] = 0;
  129.         oldpop[j].xsite = 0;
  130.         objfunc(&(oldpop[j]));       /* 计算初始适应度*/
  131.     }
  132. }
  133. void initreport()               /* 初始参数输出 */
  134. {
  135.     void   skip();
  136.     skip(outfp,1);
  137.     fprintf(outfp,"             基本遗传算法参数n");
  138.     fprintf(outfp," -------------------------------------------------n");
  139.     fprintf(outfp,"    种群大小(popsize)     =   %dn",popsize);
  140.     fprintf(outfp,"    染色体长度(lchrom)    =   %dn",lchrom);
  141.     fprintf(outfp,"    最大进化代数(maxgen)  =   %dn",maxgen);
  142.     fprintf(outfp,"    交叉概率(pcross)      =   %fn",pcross);
  143.     fprintf(outfp,"    变异概率(pmutation)   =   %fn",pmutation);
  144.     fprintf(outfp," -------------------------------------------------n");
  145.     skip(outfp,1);
  146.     fflush(outfp);
  147. }
  148. void generation()
  149. {
  150.   int mate1, mate2, jcross, j = 0;
  151.   /*  每代运算前进行预选 */
  152.   preselect();
  153.   /* 选择, 交叉, 变异 */
  154.   do
  155.     {
  156.       /* 挑选交叉配对 */
  157.       mate1 = select();
  158.       mate2 = select();
  159.       /* 交叉和变异 */
  160.       jcross = crossover(oldpop[mate1].chrom, oldpop[mate2].chrom, newpop[j].chrom, newpop[j+1].chrom);
  161.       mutation(newpop[j].chrom);
  162.       mutation(newpop[j+1].chrom);
  163.       /* 解码, 计算适应度 */
  164.       objfunc(&(newpop[j]));
  165.       /*记录亲子关系和交叉位置 */
  166.       newpop[j].parent[0] = mate1+1;
  167.       newpop[j].xsite = jcross;
  168.       newpop[j].parent[1] = mate2+1;
  169.       objfunc(&(newpop[j+1]));
  170.       newpop[j+1].parent[0] = mate1+1;
  171.       newpop[j+1].xsite = jcross;
  172.       newpop[j+1].parent[1] = mate2+1;
  173.       j = j + 2;
  174.     }
  175.   while(j < (popsize-1));
  176. }
  177. void initmalloc()              /*为全局数据变量分配空间 */
  178. {
  179.   unsigned nbytes;
  180.   char  *malloc();
  181.   int j;
  182.   /* 分配给当前代和新一代种群内存空间 */
  183.   nbytes = popsize*sizeof(struct individual);
  184.   if((oldpop = (struct individual *) malloc(nbytes)) == NULL)
  185.     nomemory("oldpop");
  186.   if((newpop = (struct individual *) malloc(nbytes)) == NULL)
  187.     nomemory("newpop");
  188.   /* 分配给染色体内存空间 */
  189.   nbytes = chromsize*sizeof(unsigned);
  190.   for(j = 0; j < popsize; j++)
  191.     {
  192.       if((oldpop[j].chrom = (unsigned *) malloc(nbytes)) == NULL)
  193. nomemory("oldpop chromosomes");
  194.       if((newpop[j].chrom = (unsigned *) malloc(nbytes)) == NULL)
  195. nomemory("newpop chromosomes");
  196.     }
  197.   if((bestfit.chrom = (unsigned *) malloc(nbytes)) == NULL)
  198.     nomemory("bestfit chromosome");
  199. }
  200. void freeall()               /* 释放内存空间 */
  201. {
  202.   int i;
  203.    for(i = 0; i < popsize; i++)
  204.     {
  205.       free(oldpop[i].chrom);
  206.       free(newpop[i].chrom);
  207.     }
  208.   free(oldpop);
  209.   free(newpop);
  210.   free(bestfit.chrom);
  211.    }
  212. void nomemory(string)        /* 内存不足,退出*/
  213.   char *string;
  214. {
  215.   fprintf(outfp,"malloc: out of memory making %s!!n",string);
  216.   exit(-1);
  217. }
  218. void report()                /* 输出种群统计结果 */
  219. {
  220.     void  repchar(), skip();
  221.     void  writepop(), writestats();
  222.     repchar(outfp,"-",80);
  223.     skip(outfp,1); 
  224.     if(printstrings == 1)
  225.     {
  226.         repchar(outfp," ",((80-17)/2));
  227.         fprintf(outfp,"模拟计算统计报告  n");
  228.         fprintf(outfp, "世代数 %3d", gen);
  229.         repchar(outfp," ",(80-28));
  230.         fprintf(outfp, "世代数 %3dn", (gen+1));
  231.         fprintf(outfp,"个体  染色体编码");
  232.         repchar(outfp," ",lchrom-5);
  233.         fprintf(outfp,"适应度    父个体 交叉位置  ");
  234.         fprintf(outfp,"染色体编码 ");
  235.         repchar(outfp," ",lchrom-5);
  236.         fprintf(outfp,"适应度n");
  237.         repchar(outfp,"-",80);
  238.         skip(outfp,1);
  239.         writepop(outfp);
  240.         repchar(outfp,"-",80);
  241.         skip(outfp,1);
  242.      }
  243.     fprintf(outfp,"第 %d 代统计: n",gen);
  244.     fprintf(outfp,"总交叉操作次数 = %d, 总变异操作数 = %dn",ncross,nmutation);
  245.     fprintf(outfp," 最小适应度:%f 最大适应度:%f  平均适应度 %fn", min,max,avg);
  246.     fprintf(outfp," 迄今发现最佳个体 =>  所在代数: %d  ", bestfit.generation);
  247.     fprintf(outfp," 适应度:%f  染色体:", bestfit.fitness);
  248.     writechrom((&bestfit)->chrom);
  249.     fprintf(outfp," 对应的变量值: %f", bestfit.varible);
  250.     skip(outfp,1);
  251.     repchar(outfp,"-",80);
  252.     skip(outfp,1);  
  253. }
  254. void writepop()
  255. {
  256.     struct individual *pind;
  257.     int j;
  258.     for(j=0; j<popsize; j++)
  259.     {
  260.         fprintf(outfp,"%3d)  ",j+1);
  261.         /* 当前代个体 */
  262.         pind = &(oldpop[j]);
  263.         writechrom(pind->chrom);
  264.         fprintf(outfp,"  %8f | ", pind->fitness);
  265.         /* 新一代个体 */
  266.         pind = &(newpop[j]);
  267.         fprintf(outfp,"(%2d,%2d)   %2d   ",
  268.         pind->parent[0], pind->parent[1], pind->xsite);
  269.         writechrom(pind->chrom);
  270.         fprintf(outfp,"  %8fn", pind->fitness);
  271.     }
  272. }
  273. void writechrom(chrom)           /* 输出染色体编码 */
  274. unsigned *chrom;
  275. {
  276.     int j, k, stop;
  277.     unsigned mask = 1, tmp;
  278.     for(k = 0; k < chromsize; k++)
  279.     {
  280.         tmp = chrom[k];
  281.         if(k == (chromsize-1))
  282.             stop = lchrom - (k*(8*sizeof(unsigned)));
  283.         else
  284.             stop =8*sizeof(unsigned);
  285.         for(j = 0; j < stop; j++)
  286.         {
  287.             if(tmp&mask)
  288.                 fprintf(outfp,"1");
  289.             else
  290.                 fprintf(outfp,"0");
  291.             tmp = tmp>>1;
  292.         }
  293.     }
  294. }
  295. void preselect()
  296. {
  297.     int j;
  298.     sumfitness = 0;
  299.     for(j = 0; j < popsize; j++) sumfitness += oldpop[j].fitness;
  300. }
  301. int select()                    /* 轮盘赌选择*/
  302. {
  303.     extern float randomperc();
  304.     float sum, pick;
  305.     int i;
  306.     pick = randomperc();
  307.     sum = 0;
  308.     if(sumfitness != 0)
  309.     {
  310.         for(i = 0; (sum < pick) && (i < popsize); i++)
  311.             sum += oldpop[i].fitness/sumfitness;
  312.     }
  313.     else
  314.         i = rnd(1,popsize);
  315.     return(i-1);
  316. }
  317. void statistics(pop)  /* 计算种群统计数据 */
  318. struct individual *pop;
  319. {
  320.     int i, j;
  321.     sumfitness = 0.0;
  322.     min = pop[0].fitness;
  323.     max = pop[0].fitness;
  324.     /* 计算最大、最小和累计适应度 */
  325.     for(j = 0; j < popsize; j++)
  326.     {
  327.         sumfitness = sumfitness + pop[j].fitness;            
  328.         if(pop[j].fitness > max) max = pop[j].fitness;        
  329.         if(pop[j].fitness < min) min = pop[j].fitness;         
  330.         /* new global best-fit individual */
  331.         if(pop[j].fitness > bestfit.fitness)
  332.   {
  333.    for(i = 0; i < chromsize; i++)
  334.     bestfit.chrom[i]      = pop[j].chrom[i];
  335.             bestfit.fitness    = pop[j].fitness;
  336.             bestfit.varible   = pop[j].varible;  
  337.             bestfit.generation = gen;
  338.   }
  339.       }
  340.     /* 计算平均适应度 */
  341.     avg = sumfitness/popsize;
  342. }
  343. void title()
  344. {
  345.   printf("SGA Optimizer Jean.Timexn");
  346. }
  347. void repchar (outfp,ch,repcount)
  348. FILE *outfp;
  349. char *ch;
  350. int repcount;
  351. {
  352.     int j;
  353.     for (j = 1; j <= repcount; j++) fprintf(outfp,"%s", ch);
  354. }
  355. void skip(outfp,skipcount)
  356. FILE *outfp;
  357. int skipcount;
  358. {
  359.     int j;
  360.     for (j = 1; j <= skipcount; j++) fprintf(outfp,"n");
  361. }
  362. void objfunc(critter)            /* 计算适应度函数值 */
  363. struct individual *critter;
  364. {
  365.     unsigned mask=1;
  366.     unsigned bitpos;
  367.     unsigned tp;
  368.     double pow(), bitpow ;
  369.     int j, k, stop;
  370.     critter->varible = 0.0;
  371.     for(k = 0; k < chromsize; k++)
  372.     {
  373.         if(k == (chromsize-1))
  374.             stop = lchrom-(k*(8*sizeof(unsigned)));
  375.         else
  376.             stop =8*sizeof(unsigned);
  377.         tp = critter->chrom[k];
  378.         for(j = 0; j < stop; j++)
  379.         {
  380.             bitpos = j + (8*sizeof(unsigned))*k;
  381.             if((tp&mask) == 1)
  382.             {
  383.                 bitpow = pow(2.0,(double) bitpos);
  384.                 critter->varible = critter->varible + bitpow;
  385.             }
  386.             tp = tp>>1;
  387.         }
  388.     }
  389.     critter->varible =-1+critter->varible*3/(pow(2.0,(double)lchrom)-1);
  390.     critter->fitness =critter->varible*sin(critter->varible*10*atan(1)*4)+2.0;
  391. }
  392. void  mutation(unsigned *child)   /*变异操作*/
  393. {
  394.     int j, k, stop;
  395.     unsigned mask, temp = 1;
  396.     for(k = 0; k < chromsize; k++)
  397.     {
  398.         mask = 0;
  399.         if(k == (chromsize-1))
  400.             stop = lchrom - (k*(8*sizeof(unsigned)));
  401.         else
  402.             stop = 8*sizeof(unsigned);
  403.         for(j = 0; j < stop; j++)
  404.         {
  405.             if(flip(pmutation))
  406.             {
  407.                 mask = mask|(temp<<j);
  408.                 nmutation++;
  409.             }
  410.         }
  411.         child[k] = child[k]^mask;
  412.     }
  413. }
  414. int crossover (unsigned *parent1, unsigned *parent2, unsigned *child1, unsigned *child2)
  415. /* 由两个父个体交叉产生两个子个体 */
  416. {
  417.     int j, jcross, k;
  418.     unsigned mask, temp;
  419.     if(flip(pcross))
  420.     {
  421.         jcross = rnd(1 ,(lchrom - 1));/* Cross between 1 and l-1 */
  422.         ncross++;
  423.         for(k = 1; k <= chromsize; k++)
  424.         {
  425.             if(jcross >= (k*(8*sizeof(unsigned))))
  426.             {
  427.                 child1[k-1] = parent1[k-1];
  428.                 child2[k-1] = parent2[k-1];
  429.             }
  430.             else if((jcross < (k*(8*sizeof(unsigned)))) && (jcross > ((k-1)*(8*sizeof(unsigned)))))
  431.             {
  432.                 mask = 1;
  433.                 for(j = 1; j <= (jcross-1-((k-1)*(8*sizeof(unsigned)))); j++)
  434.                 {
  435.                     temp = 1;
  436.                     mask = mask<<1;
  437.                     mask = mask|temp;
  438.                 }
  439.                 child1[k-1] = (parent1[k-1]&mask)|(parent2[k-1]&(~mask));
  440.                 child2[k-1] = (parent1[k-1]&(~mask))|(parent2[k-1]&mask);
  441.             }
  442.             else
  443.             {
  444.                 child1[k-1] = parent2[k-1];
  445.                 child2[k-1] = parent1[k-1];
  446.             }
  447.         }
  448.     }
  449.     else
  450.     {
  451.         for(k = 0; k < chromsize; k++)
  452.         {
  453.             child1[k] = parent1[k];
  454.             child2[k] = parent2[k];
  455.         }
  456.         jcross = 0;
  457.     }
  458.     return(jcross);
  459. }
  460. void advance_random()          /* 产生55个随机数 */
  461. {
  462.     int j1;
  463.     double new_random;
  464.     for(j1 = 0; j1 < 24; j1++)
  465.     {
  466.         new_random = oldrand[j1] - oldrand[j1+31];
  467.         if(new_random < 0.0) new_random = new_random + 1.0;
  468.         oldrand[j1] = new_random;
  469.     }
  470.     for(j1 = 24; j1 < 55; j1++)
  471.     {
  472.         new_random = oldrand [j1] - oldrand [j1-24];
  473.         if(new_random < 0.0) new_random = new_random + 1.0;
  474.         oldrand[j1] = new_random;
  475.     }
  476. }
  477. int flip(float prob)          /* 以一定概率产生0或1 */
  478. {
  479.     float randomperc();
  480.     if(randomperc() <= prob)
  481.         return(1);
  482.     else
  483.         return(0);
  484. }
  485. void randomize()            /* 设定随机数种子并初始化随机数发生器 */
  486. {
  487.     float randomseed;
  488.     int j1;
  489.     for(j1=0; j1<=54; j1++)
  490.       oldrand[j1] = 0.0;
  491.     jrand=0;
  492.     randomseed=0.5;
  493.     warmup_random(randomseed);
  494. }
  495. double randomnormaldeviate()         /* 产生随机标准差 */
  496. {
  497.     double sqrt(), log(), sin(), cos();
  498.     float randomperc();
  499.     double t, rndx1;
  500.     if(rndcalcflag)
  501.     {   rndx1 = sqrt(- 2.0*log((double) randomperc()));
  502.         t = 6.2831853072 * (double) randomperc();
  503.         rndx2 = rndx1 * sin(t);
  504.         rndcalcflag = 0;
  505.         return(rndx1 * cos(t));
  506.     }
  507.     else
  508.     {
  509.         rndcalcflag = 1;
  510.         return(rndx2);
  511.     }
  512. }
  513. float randomperc()            /*与库函数random()作用相同, 产生[0,1]之间一个随机数 */
  514. {
  515.     jrand++;
  516.     if(jrand >= 55)
  517.     {
  518.         jrand = 1;
  519.         advance_random();
  520.     }
  521.     return((float) oldrand[jrand]);
  522. }
  523. int rnd(low, high)           /*在整数low和high之间产生一个随机整数*/
  524. int low,high;
  525. {
  526.     int i;
  527.     float randomperc();
  528.     if(low >= high)
  529.         i = low;
  530.     else
  531.     {
  532.         i = (randomperc() * (high - low + 1)) + low;
  533.         if(i > high) i = high;
  534.     }
  535.     return(i);
  536. }
  537. void warmup_random(float random_seed)       /* 初始化随机数发生器*/
  538. {
  539.     int j1, ii;
  540.     double new_random, prev_random;
  541.     oldrand[54] = random_seed;
  542.     new_random = 0.000000001;
  543.     prev_random = random_seed;
  544.     for(j1 = 1 ; j1 <= 54; j1++)
  545.     {
  546.         ii = (21*j1)%54;
  547.         oldrand[ii] = new_random;
  548.         new_random = prev_random-new_random;
  549.         if(new_random<0.0) new_random = new_random + 1.0;
  550.         prev_random = oldrand[ii];
  551.     }
  552.     advance_random();
  553.     advance_random();
  554.     advance_random();
  555.     jrand = 0;
  556. }
  557. main(argc,argv)           /*  主程序  */
  558. int argc;
  559. char *argv[];
  560. {
  561.     struct individual *temp;
  562.     FILE   *fopen();
  563.     void   title();
  564.     char   *malloc();
  565.     //if(rtrim(argv[1])=="")
  566. argv[1]="outfp.txt";
  567. if((outfp = fopen(argv[1],"w")) == NULL)
  568.         {
  569.            fprintf(stderr,"Cannot open output file %sn",argv[1]);
  570.             exit(-1);
  571.         }
  572.      title();
  573.      maxruns=10;
  574.      for(run=1; run<=maxruns; run++)
  575.     {
  576.         initialize();
  577.         for(gen=0; gen<maxgen; gen++)
  578.         {
  579.          fprintf(outfp,"n第 %d / %d 次运行: 当前代为 %d, 共 %d 代n", run,maxruns,gen,maxgen);
  580.             /* 产生新一代 */
  581.             generation();
  582.             /* 计算新一代种群的适应度统计数据 */
  583.             statistics(newpop);
  584.             /* 输出新一代统计数据 */
  585.             report();
  586.             temp = oldpop;
  587.             oldpop = newpop;
  588.             newpop = temp;
  589.         }
  590.         freeall();
  591.     }
  592. }