- /*baixzh SYSU 2008-12-16 */
- #include<iostream>
- #include<string>
- #include<math.h>
- #include<cstdlib>
- #include<algorithm>
- using namespace std;
- int i;int j; //循环变量
- int t=0;//选择代数
- struct city//城市节点
- {
- double x;
- double y;
- city();
- };
- city::city()
- {
- x=0.0;
- y=0.0;
- }
- double pos[20]=//初始城市坐标数据
- {
- 0.400, 0.4439,//代表x,y
- 0.2439, 0.1463,
- 0.1707, 0.2293,
- 0.2293, 0.7610,
- 0.5171, 0.9414,
- 0.8732, 0.6536,
- 0.6878, 0.5219,
- 0.8488, 0.3609,
- 0.6683, 0.2536,
- 0.6195, 0.2634
- };
- city c_t[10];
- double dis[10][10];//城市距离矩阵
- struct c_gen
- {
- string route;//旅行商路径也代表基因编码
- double lenth;//路径长度
- double p;//基因的概率
- c_gen();
- };
- c_gen::c_gen()
- {
- route="";
- lenth=0.0;
- p=0.0;
- };
- c_gen group[100];//种群
- void init_population();//初始化种群
- void cal_p();//种群中各个基因概率计算
- void select();//选择函数 淘汰33%
- void mating();//交配
- void aberrance();//变异
- void replace_population();//代替旧种群
- bool cmp(c_gen a,c_gen b)//自定义排序比较函数
- {
- return a.lenth <b.lenth ;
- }
- void init_population()
- {
- for(i=0;i<100;i++)
- {
- int an[10]={2,5,4,9,8,7,0,1,6,3} ;//给出一个原始祖先
- int ran1=rand()%10;
- int ran2=rand()%10;
- if(ran1==ran2)
- {
- ran2=(ran2+rand()%5+1)%10;
- }
- swap(an[ran1],an[ran2]);
- swap(an[(ran1+9)%10],an[(ran1+4)%10]);
- for(j=0;j<10;j++)
- {
- group[i].route+=char(an[j]+'0');
- }
- //产生100个随机的初始祖先 组成种群
- for(j=0;j<9;j++)
- {
- group[i].lenth +=dis[group[i].route[j]-'0'][group[i].route[j+1]-'0'];
- }
- group[i].lenth +=dis[group[i].route[0]-'0'][group[i].route[9]-'0'];
- }
- return ;
- }
- void cal_p()
- {
- double sum=0.0;
- for(i=0;i<100;i++)
- {
- sum+=group[i].lenth ;
- }
- for(i=0;i<100;i++)
- {
- group[i].p=group[i].lenth /sum;
- }
- return ;
- }
- void select()
- {
- sort(group,group+100,cmp);//种群按照评价值进行排序
- cout<<"第"<<t<<"代最优品种: " ;
- for(int temp=0;temp<10;temp++)
- {
- cout<<char(group[0].route [temp]-'0'+'A')<<"-->";
- }
- cout<<char(group[0].route [0]-'0'+'A')<<endl;
- cout<<"路径长度为: "<<group[0].lenth <<endl;
- return ;
- }
- void mating()//种群规模100 0-65的优秀品种交配 66保留 67-99品种淘汰 被交配的子代代替
- {
- for(i=0;i<33;i++)
- {
- int ran1=rand()%10;
- int ran2=rand()%10;
- if(ran1==ran2)
- {
- ran2=(ran2+2)%10;
- }
- char c1=group[i*2].route [ran1];
- char c2=group[i*2].route [ran2];
- //偶数基因中随机选出2段染色体然后从奇数基因中除去这2段染色体 再将这2段随机插入产生子代
- string t=group[i*2+1].route ;
- int t1,t2;
- int temp;
- bool k1=false;
- bool k2=false;
- for(temp=0;temp<10;temp++)
- {
- if(t[temp]==c1)
- {
- t.erase ( temp,1);
- }
- }
- for(temp=0;temp<9;temp++)
- {
- if(t[temp]==c2)
- {
- t.erase ( temp,1);
- }
- }
- int ran3=rand()%8;
- t.insert (t.begin ()+ran3,c1);
- t.insert (t.begin ()+(ran3+rand())%8,c2);
- group[67+i].route =t;//子代产生 加入种群
- }
- return ;
- }
- void aberrance()
- {
- int ran1=rand()%100;
- int ran2=rand()%10;
- int ran3=rand()%10;
- if(ran2==ran3)
- {
- ran3=(ran3+rand()%5+1)%10;
- }
- swap(group[ran1].route [ran2],group[ran1].route [ran3]);
- //随机选出一段基因,然后随机交换2个染色体位置 产生变异
- return ;
- }
- void replace_population()
- {
- for(i=0;i<100;i++)
- {
- group[i].lenth =0.0;
- for(j=0;j<9;j++)
- {
- group[i].lenth +=dis[group[i].route[j]-'0'][group[i].route[j+1]-'0'];
- }
- group[i].lenth +=dis[group[i].route[0]-'0'][group[i].route[9]-'0'];
- }
- //新种群的评价值重新计算,代替原种群
- }
- int main()
- {
- for(i=0;i<10;i++)
- {
- c_t[i].x=pos[i*2];
- c_t[i].y=pos[i*2+1];
- }//城市节点初始化
- memset(dis,0.0,sizeof(dis));
- for(i=0;i<10;i++)
- for(j=0;j<10;j++)
- {
- dis[i][j]=sqrt(pow((c_t[i].x -c_t[j].x),2) +pow((c_t[i].y-c_t[j].y),2)) ;
- }
- //距离矩阵初始化
- init_population();//种群初始化
- //遗传算法主体,经过50代的最优解完全符合最优解的条件
- for(t=0;t<50;t++)
- {
- select();
- mating();
- aberrance();
- replace_population();
- }
- return 0;
- }
遗传算法解决tsp问题
最新推荐文章于 2022-11-09 12:25:51 发布