遗传算法程序出错,请大家改正,急!谢谢大家~

程序是对工序进行排列,使工人总的工资成本最低。
C编的,VS08报错说某些位置读取发生冲突。

麻烦大家帮忙改改吧~很急,谢谢~~

源程序如下:

#include <stdio.h>

#include<stdlib.h>

#include<time.h>

#include<math.h>

#include<conio.h>

 

#defineN 5      

#defineM 2          //5个工序,2个工人

#definePOPSIZE 500  

 

intc[M]={2,5};         //工人每小时工作成本

intT[M]={3,2};         //每个工人参与工序的总次数

intJ[M][N];            //记录工人在某个工序参加与否

inta[M][N]={{1,2,3},{3,4,5}};  //每个工人参加的工序集

 

 int popsize ;                         //种群大小

 int maxgeneration;                   //最大世代数

 double pcross = 0.0;                 //交叉率

 double pmutation = 0.0;              //变异率

 double sumfitness;                                     //种群个体适应值累计

 

 

 struct individual                     //定义染色体个体结构体

 {

         int  chrom[N];              //定义染色体二进制表达形式

         doublefitness;                       //染色体的适应值

 };

 

 

intgeneration;                       //当前执行的世代数

intbest_index;                       //本世代最好的染色体索引序号

 

structindividual bestindividual;     //最佳染色体个体

structindividual currentbest;        //当前最好的染色体个体currentbest

intbestgeneration;                                     //当前最好染色体个体产生的代数

structindividual oldpop[POPSIZE];//种群数组

structindividual newpop[POPSIZE];//新种群数组

 

/* 随机数发生器使用的静态变量*/

static double oldrand[55];

static int jrand;

static double rndx2;

static int rndcalcflag;

 

//函数声明

voidprintline(FILE *);                                   

voidinitialoldpop(FILE *ffp);     //初始化当代种群    

voidgeneratenextpop(FILE *ffp);  //产生下一代种群

voidevaluateoldpop();            //评价种群

voidcalculateobjectfitness();        //计算种群适应度

voidfindbestindividual();    //寻找最好的染色体个体

 

intselect();                //选择操作

                             //将p中移除掉q中位置在j1,j2之间的元素,其余元素前移,返回剩下元素的数量

intsearchanddelete(int *p,int*q,int j1,intj2);

voidcrossover(int *,int*,int *,int*,FILE *ffp);            //交叉操作

voidmutation(int *);                                         //变异操作

voidinput();                                                //输入接口

voidoutputtextreport(FILE *ffp);             //每代输出文字报告

voidreport(FILE *ffp);                       //输出最终结果报告

 

//以下为一些随机数相关函数

voidadvance_random();

intflip(double);intrnd(int, int);

voidrandomize();

doublerandomnormaldeviate();

floatrandomperc();float rndreal(float,float);

voidwarmup_random(float);

 

voidmain()    //主函数       (函数主体开始)

{

 

        int i;

       

        FILE*fp;          //指针文件

       

                            //打开文本文件

        if((fp= fopen("Result.txt","w+"))==NULL)

        {

                printf("Can not open file!\n");

        }

   fprintf(fp,"本程序为使用基本SGA求解Talent Scheduling问题\n"); 

   generation=0;                   //初始化generation当前执行的代

   input();                        //初始化种群大小、交叉率、变异率

   

    

   randomize();           // 初始化随机数发生器

   initialoldpop(fp);    //产生初始化种群

        evaluateoldpop();

   while(generation<maxgeneration) //小于最大世代数,执行循环体

        {

                generation++;                  

                generatenextpop(fp);        //生成子代种群(A.选择; B.交叉;C.变异)

                for(i = 0 ; i < popsize ; i++)

                {

                        oldpop[i]=newpop[i];    

                }

                evaluateoldpop();            //评价新生子代种群

                outputtextreport(fp);        //输出当前子代种群统计报告

        }

      

        report(fp);                       //输出最终报告

        fclose(fp);                       //关闭fp指向的文件句柄,防止句柄泄露

 

        printf("计算结果已输出到Result.txt文件中。);

        system("pause");

       

}

 

voidprintline(FILE *ffp)

{

        fprintf(ffp,"\n*************************************************************\n");

}

 

voidinitialoldpop(FILE *ffp)  //种群初始化,对种群中每条染色体,生成-5的不重复序列

{

       

        int i,p,q,r;

        srand(   (unsigned)time(   NULL  )   );

        for (i=0;i<popsize; i++)

        { 

                int a[N]={0,1,2,3,4};      

                p=N; 

                q=0;

                while(p> 0)  //对oldpop[i]染色体生成随机序列  

                {  

                        r=rand();                        

                        r%=p;                           

                        oldpop[i].chrom[q]=a[r];

                        a[r]=a[p-1];     //  把后一个移到刚生成的位置             

                        q++;

                        p--;

                }    

        }      

       

       

       

}

 

voidgeneratenextpop(FILE *ffp)  //生成下一代

{

        int mate1,mate2,j=0;

        do{

                //挑选交叉配对

                mate1=select();

                mate2=select();

                crossover(oldpop[mate1].chrom,oldpop[mate2].chrom,newpop[j].chrom,newpop[j+1].chrom,ffp);

                mutation(newpop[j].chrom);

                mutation(newpop[j+1].chrom);

                j=j+2; 

        }

        while(j<(popsize-1));

}

 

 

 

voidevaluateoldpop()   //评价种群

{

  calculateobjectfitness();       //计算种群个体的适应度

  findbestindividual();           //找到最好和最差的染色体个体

}

 

 

 

voidcalculateobjectfitness()  //计算染色体个体适应值

  int i,j,k,l,s,r,x;

  int p=0;

  int temp;

  int u[N]={1,2,1,2,1};

  int X[M]={0,0};

 

  for(i=0;i<popsize;i++)

 {

        oldpop[i].fitness=0.0;

   for(s=0;s<N;s++)

        {

                r=oldpop[i].chrom[s];

            temp=u[r];

       u[r]=u[s];

       u[s]=temp;

        }

          for(j=0;j<M;j++)

          {

                  for(k=0;k<N;k++)

              for(l=0;l<N;l++)

                  {

                          if(a[j][k]==oldpop[i].chrom[l])

                       J[j][l]=1;

                        else

                       J[j][l]=0;                                        //记录各个工人在随机工序序列中的参与位置

                  }

 

                while(J[j][p]!=1)

                {

                        p++;

                }

                 x=1;

        X[j]=u[p];

 

                 while(x<T[j])

                 {

                         p++;

                     X[j]=X[j]+u[p];

                     if(J[j][p]==1)

                         x++;

                 }

          }

          for(j=0;j<M;j++)

                 oldpop[i].fitness=oldpop[i].fitness+X[j]*c[j];

 }

}

 

 

voidfindbestindividual( ) //求最佳个体

{

        int i;

        sumfitness=0.0;

        bestindividual=oldpop[0];

        best_index=0;

        sumfitness+=oldpop[0].fitness;

        currentbest.fitness=oldpop[0].fitness;

 

        for(generation=0;generation<maxgeneration;generation++)

         for(i=1;i<popsize; i++)

        {

                if (oldpop[i].fitness<bestindividual.fitness)       //依次比较,找出最佳个体            

                {       bestindividual=oldpop[i];                       //(选适应值最小的)

                        best_index=i;

                }

               

                sumfitness+=oldpop[i].fitness;                              // 存放种群总体适应值

        }

       

        if(bestindividual.fitness<currentbest.fitness)//第n代最好的,通过比较小于以往最好个体的话,暂时存放在currentbest

        {

                currentbest=bestindividual;

                bestgeneration=generation;

        }

       

}

 

                                             //将p[]中移除掉q[]中位置在j1,j2之间的元素,其余元素前移,返回剩下元素的数量

intsearchanddelete(int *p,int*q,int j1,intj2)

{

        int num=N;

        int i,j;       

 

        for(j=j1;j<j2;j++)

                        for(i=0;i<num;i++)

                        {       if(q[j]==p[i])

                                {       while((i+1)<num)

                                        {      

                                                p[i]=p[i+1];

                                                i++;

                                        }

                                        num--;//删除一个元素,计数器减一       

                                }                      

                        }

 

 

        num=N-(j2-j1);//计算剩下元素的数目

 

        return num;    

}

 

intselect() //轮盘赌选择

{

        float randomperc();

       

        double sum,pick;

        int i;

       

        pick=randomperc();//产生[0,]上随机数

        sum=0.0;

        if(sumfitness!=0)

        {

                for(i=0;(sum<pick)&&(i<popsize);i++)

                        sum+=sumfitness-oldpop[i].fitness/sumfitness;   

               

        }

        else

                i=rnd(1,popsize); 

       

        return(i-1);

}

 

 

 

voidcrossover(int *parent1,int*parent2,int *child1,int*child2,FILE *ffp) //ox交叉算法

{

       

        int i,j;

        int jcross1,jcross2;//交叉位置

        int temp;

        int num1,num2;

 

        int temp1[N],temp2[N];//分别作为暂存parent1,parent2的数组

       

        for(i=0;i<N;i++)

        {

                temp1[i]=parent1[i];

                temp2[i]=parent2[i];

 

        }

       

        if(flip(pcross))

        {

                                 //在和N-1之间随机产生两个交叉位置值

                jcross1=-1;

                jcross2=-1;

                while(jcross1==jcross2)

                {

                        jcross1=rand()%(N-1)+1;

                        jcross2=rand()%(N-1)+1;

                }

                if(jcross1>jcross2)

                {

                        temp=jcross1;

                        jcross1=jcross2;

                        jcross2=temp;

                }

 

                //将切割点之间的元素复制到后代的切割点之间

                j=jcross1;

                while(j<jcross2)

                {

                        child1[j]=temp1[j];

                        child2[j]=temp2[j];

                        j++;

                }

       

               

        //将parent2中,除掉child1中位置在jcross1,jcross2之间的元素,其余元素前移,返回剩下元素的数量

                num1=searchanddelete(temp2,child1,jcross1,jcross2);

 

                //将parent1中,除掉child2中位置在jcross1,jcross2之间的元素,其余元素前移,返回剩下元素的数量

                num2=searchanddelete(temp1,child2,jcross1,jcross2);

 

               

                //将去掉多余元素的parent2中值复制到child1中,避开jcross1,jcross2之间的元素

                j=0;i=0;

                while(j<jcross1)

                {

                        child1[j]=temp2[i];

                        i++;

                        j++;

                       

                }              

               

               

                j=jcross2;//数组下标避开jcross1,jcross2之间的元素

                while(i<num1)

                {

                        child1[j]=temp2[i];

                        i++;

                        j++;

                       

                }

               

               

                //将去掉多余元素的parent1中值复制到child2中,避开jcross1,jcross2之间的元素

                j=0;i=0;

                while(j<jcross1)

                {              

                        child2[j]=temp1[i];

                        i++;

                        j++;

                       

                }              

               

                j=jcross2;//数组下标避开jcross1,jcross2之间的元素

                while(i<num2)

                {

                        child2[j]=temp1[i];

                        i++;

                        j++;

                       

                }

                               

                               

        }//if

 

        else

        {      

                for(i=0;i<N;i++)

                {

                        child1[i]=temp1[i];

                        child2[i]=temp2[i];

                       

                }

 

        }

       

}

 

 

voidmutation(int *child) //变异是在染色体上随机地选择两点,交换其编码

{

       

        int i;

        int j1,j2,temp;

       

        for(i=0;i<N;i++)

        {

               

                if (flip(pmutation))

                {

                        j1=rand()%(N-1)+1;

                        j2=rand()%(N-1)+1;

                        temp=child[j1];

                        child[j1]=child[j2];

                        child[j2]=temp;

                       

                }

        }       

       

}

 

 

 

 void input() //数据输入

 {

         

         printf("初始化全局变量:\n");

         

         printf("    种群大小(50-500偶数):");

         scanf("%d",&popsize);                //输入种群大小,必须为偶数

         if((popsize%2)!= 0)         

         {

                 printf( "   种群大小设置为偶数\n");

                 popsize++;

         }

         printf("     最大世代数(100-300):"); //输入最大世代数

         scanf("%d",&maxgeneration);

         printf("     交叉率(0.2-0.99):");    //输入交叉率

         scanf("%lf",&pcross);

         printf("     变异率(0.001-0.1):");   //输入变异率

         scanf("%lf",&pmutation);

         

 }

 

 

 

 void outputtextreport(FILE *ffp)//数据输出

 {

        int i;

 

        printline(ffp);

 

        fprintf(ffp,"\n\t当前世代=%d\n",generation);

 

        fprintf(ffp,"本世代最好的染色体为:\n");

        for(i=0;i<N;i++)

                fprintf(ffp," %d",bestindividual.chrom[i]);

 

        fprintf(ffp,"\n总长度(相对长度)为%6.1f",currentbest.fitness);

         

 }

 

 void report(FILE *ffp)

 {

         

        int i;

       

        fprintf(ffp,"\n");

        fprintf(ffp,"         统计结果:        ");

        fprintf(ffp,"\n");

 

        fprintf(ffp,"\n种群数:%d",popsize);

        fprintf(ffp,"\n最大世代数:%d",maxgeneration);

        fprintf(ffp,"\n交叉率:%5.1f",pcross);

        fprintf(ffp,"\n变异率:%5.1f",pmutation);

 

        fprintf(ffp,"\n最终求得tsp问题的最短路径解");

        fprintf(ffp,"产生于%d代",bestgeneration);

        fprintf(ffp,"\n其染色体编码为:");

       

        for( i = 0 ; i < N ; i++ )

                fprintf(ffp," %d-",currentbest.chrom[i]);

        fprintf(ffp,"\n总长度(相对长度)为%6.1f",currentbest.fitness);

        fprintf(ffp,"\n");

       

         

         

 }

 

 

voidadvance_random()          // 产生个随机数

{

   int j1;

   double new_random;

   for(j1 = 0; j1 < 24; j1++)

   {

       new_random = oldrand[j1] - oldrand[j1+31];

       if(new_random < 0.0) new_random =new_random + 1.0;

       oldrand[j1] = new_random;

   }

   for(j1 = 24; j1 < 55; j1++)

   {

       new_random = oldrand [j1] - oldrand [j1-24];

       if(new_random < 0.0) new_random =new_random + 1.0;

       oldrand[j1] = new_random;

   }

}

 

intflip(double prob)          //以一定概率产生或

{

 

   if(randomperc() <= prob)

       return(1);

   else

       return(0);

}

 

voidrandomize()            /* 设定随机数种子并初始化随机数发生器*/

{

   float randomseed;

   int j1;

   for(j1=0; j1<=54; j1++)

     oldrand[j1] = 0.0;

   jrand=0;

     do

       {

             printf("请输入随机数种子[0-1]:\n");

                         scanf("%f",&randomseed);

        }

       while((randomseed < 0.0) ||(randomseed > 1.0));

   warmup_random(randomseed);

}

 

doublerandomnormaldeviate()         // 产生随机标准差

{

 

   double t, rndx1;

   if(rndcalcflag)

   {   rndx1 = sqrt(- 2.0*log((double) randomperc()));

       t = 6.2831853072 * (double)randomperc();

       rndx2 = rndx1 * sin(t);

       rndcalcflag = 0;

       return(rndx1 * cos(t));

   }

   else

   {

       rndcalcflag = 1;

       return(rndx2);

   }

}

 

 

floatrandomperc()            //与库函数random()作用相同,产生[0,1]之间一个随机数

{

   jrand++;

   if(jrand >= 55)

   {

       jrand = 1;

       advance_random();

   }

   return((float)oldrand[jrand]);

}

 

 

intrnd(int low,inthigh)           //在整数low和high之间产生一个随机整数

{

   int i;

 

   if(low >= high)

       i = low;

   else

   {

       i = ((int)randomperc() * (high - low +1)) + low;

       if(i > high) i = high;

   }

   return(i);

}

 

voidwarmup_random(float random_seed)       //初始化随机数发生器

{

   int j1, ii;

   double new_random, prev_random;

 

   oldrand[54] = random_seed;

   new_random = 0.000000001;

   prev_random = random_seed;

   for(j1 = 1 ; j1 <= 54; j1++)

   {

       ii = (21*j1)%54;

       oldrand[ii] = new_random;

       new_random = prev_random-new_random;

       if(new_random<0.0) new_random =new_random + 1.0;

       prev_random = oldrand[ii];

   }

   advance_random();

   advance_random();

   advance_random();

   jrand = 0;

}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值