#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define cities 10 //城市的个数
#define MAXX 100//迭代次数
#define pc 0.8 //交配概率
#define pm 0.05 //变异概率
#define num 10//种群的大小
int bestsolution;
int distance[cities][cities];
struct group
{
int city[cities];
int adapt;
double p;
}group[num],grouptemp[num];
void init()
{
int i,j;
memset(distance,0,sizeof(distance));
srand((unsigned)time(NULL));
for(i=0;i<cities;i++)
{
for(j=i+1;j<cities;j++)
{
distance[i][j]=rand()%100;
distance[j][i]=distance[i][j];
}
}
printf("城市的距离矩阵如下\n");
for(i=0;i<cities;i++)
{
for(j=0;j<cities;j++)
printf("%4d",distance[i][j]);
printf("\n");
}
}
void groupproduce()
{
int i,j,t,k,flag;
for(i=0;i<num;i++)
for(j=0;j<cities;j++)
group[i].city[j]=-1;
srand((unsigned)time(NULL));
for(i=0;i<num;i++)
{
for(j=0;j<cities;)
{
t=rand()%cities;
flag=1;
for(k=0;k<j;k++)
{
if(group[i].city[k]==t)
{
flag=0;
break;
}
}
if(flag)
{
group[i].city[j]=t;
j++;
}
}
}
printf("初始的种群\n");
for(i=0;i<num;i++)
{
for(j=0;j<cities;j++)
printf("%4d",group[i].city[j]);
printf("\n");
}
}
void pingjia()
{
int i,j;
int n1,n2;
int sumdistance,biggestsum=0;
double biggestp=0;
for(i=0;i<num;i++)
{
sumdistance=0;
for(j=1;j<cities;j++)
{
n1=group[i].city[j-1];
n2=group[i].city[j];
sumdistance+=distance[n1][n2];
}
group[i].adapt=sumdistance;
biggestsum+=sumdistance;
}
for(i=0;i<num;i++)
{
group[i].p=1-(double)group[i].adapt/(double)biggestsum;
biggestp+=group[i].p;
}
for(i=0;i<num;i++)
group[i].p=group[i].p/biggestp;
bestsolution=0;
for(i=0;i<num;i++)
if(group[i].p>group[bestsolution].p)
bestsolution=i;
for(i=0;i<num;i++)
printf("染色体%d的路径之和与生存概率分别为%4d %.4f\n",i,group[i].adapt,group[i].p);
printf("当前种群的最优染色体是%d号染色体\n",bestsolution);
}
void xuanze()
{
int i,j,temp;
double gradient[num];
double xuanze[num];
int xuan[num];
for(i=0;i<num;i++)
{
gradient[i]=0.0;
xuanze[i]=0.0;
}
gradient[0]=group[0].p;
for(i=1;i<num;i++)
gradient[i]=gradient[i-1]+group[i].p;
srand((unsigned)time(NULL));
for(i=0;i<num;i++)
{
xuanze[i]=(rand()%100);
xuanze[i]/=100;
}
for(i=0;i<num;i++)
{
for(j=0;j<num;j++)
{
if(xuanze[i]<gradient[j])
{
xuan[i]=j;
break;
}
}
}
for(i=0;i<num;i++)
{
grouptemp[i].adapt=group[i].adapt;
grouptemp[i].p=group[i].p;
for(j=0;j<cities;j++)
grouptemp[i].city[j]=group[i].city[j];
}
for(i=0;i<num;i++)
{
temp=xuan[i];
group[i].adapt=grouptemp[temp].adapt;
group[i].p=grouptemp[temp].p;
for(j=0;j<cities;j++)
group[i].city[j]=grouptemp[temp].city[j];
}
}
void jiaopei()
{
int i,j,k,kk;
int t;
int point1,point2,temp;
int pointnum;
int temp1,temp2;
int map1[cities],map2[cities];
double jiaopeip[num];
int jiaopeiflag[num];
for(i=0;i<num;i++)
jiaopeiflag[i]=0;
srand((unsigned)time(NULL));
for(i=0;i<num;i++)
{
jiaopeip[i]=(rand()%100);
jiaopeip[i]/=100;
}
t=0;
for(i=0;i<num;i++)
{
if(jiaopeip[i]<pc)
{
jiaopeiflag[i]=1;
t++;
}
}
t=t/2*2;
srand((unsigned)time(NULL));
temp1=0;
for(i=0;i<t/2;i++)
{
point1=rand()%cities;
point2=rand()%cities;
for(j=temp1;j<num;j++)
if(jiaopeiflag[j]==1)
{
temp1=j;
break;
}
for(j=temp1+1;j<num;j++)
if(jiaopeiflag[j]==1)
{
temp2=j;
break;
}
if(point1>point2)
{
temp=point1;
point1=point2;
point2=temp;
}
memset(map1,-1,sizeof(map1));
memset(map2,-1,sizeof(map2));
for(k=point1;k<=point2;k++)
{
map1[group[temp1].city[k]]=group[temp2].city[k];
map2[group[temp2].city[k]]=group[temp1].city[k];
}
for(k=0;k<point1;k++)
{
temp=group[temp1].city[k];
group[temp1].city[k]=group[temp2].city[k];
group[temp2].city[k]=temp;
}
for(k=point2+1;k<cities;k++)
{
temp=group[temp1].city[k];
group[temp1].city[k]=group[temp2].city[k];
group[temp2].city[k]=temp;
}
for(k=0;k<point1;k++)
{
for(kk=point1;kk<=point2;kk++)
if(group[temp1].city[k]==group[temp1].city[kk])
{
group[temp1].city[k]=map1[group[temp1].city[k]];
break;
}
}
for(k=point2+1;k<cities;k++)
{
for(kk=point1;kk<=point2;kk++)
if(group[temp1].city[k]==group[temp1].city[kk])
{
group[temp1].city[k]=map1[group[temp1].city[k]];
break;
}
}
for(k=0;k<point1;k++)
{
for(kk=point1;kk<=point2;kk++)
if(group[temp2].city[k]==group[temp2].city[kk])
{
group[temp2].city[k]=map2[group[temp2].city[k]];
break;
}
}
for(k=point2+1;k<cities;k++)
{
for(kk=point1;kk<=point2;kk++)
if(group[temp2].city[k]==group[temp2].city[kk])
{
group[temp2].city[k]=map2[group[temp2].city[k]];
break;
}
}
temp1=temp2+1;
}
}
void bianyi()
{
int i,j;
int t;
int temp1,temp2,point;
double bianyip[num];
int bianyiflag[num];
for(i=0;i<num;i++)
bianyiflag[i]=0;
srand((unsigned)time(NULL));
for(i=0;i<num;i++)
{
bianyip[i]=(rand()%100);
bianyip[i]/=100;
}
t=0;
for(i=0;i<num;i++)
{
if(bianyip[i]<pm)
{
bianyiflag[i]=1;
t++;
}
}
srand((unsigned)time(NULL));
for(i=0;i<num;i++)
{
if(bianyiflag[i]==1)
{
temp1=rand()%10;
temp2=rand()%10;
point=group[i].city[temp1];
group[i].city[temp1]=group[i].city[temp2];
group[i].city[temp2]=point;
}
}
}
int main()
{
int i,j,t;
init();
groupproduce();
pingjia();
t=0;
while(t++<MAXX)
{
xuanze();
bianyi();
pingjia();
}
printf("\n输出最终的种群评价\n");
for(i=0;i<num;i++)
{
for(j=0;j<cities;j++)
{
printf("%4d",group[i].city[j]);
}
printf(" adapt:%4d, p:%.4f\n",group[i].adapt,group[i].p);
}
printf("最优解为%d号染色体\n",bestsolution);
return 0;
}