遗传算法解决tsp问题

  1. /*baixzh SYSU 2008-12-16 */
  2. #include<iostream>
  3. #include<string>
  4. #include<math.h>
  5. #include<cstdlib>
  6. #include<algorithm>
  7. using namespace std;
  8. int i;int j;    //循环变量
  9. int t=0;//选择代数
  10. struct city//城市节点
  11. {
  12.     double x;
  13.     double y;
  14.     city(); 
  15. };
  16. city::city() 
  17. {
  18.     x=0.0;
  19.     y=0.0;
  20. }
  21. double pos[20]=//初始城市坐标数据
  22.     {
  23.         0.400,  0.4439,//代表x,y
  24.         0.2439, 0.1463,
  25.         0.1707, 0.2293,
  26.         0.2293, 0.7610,
  27.         0.5171, 0.9414,
  28.         0.8732, 0.6536,
  29.         0.6878, 0.5219,
  30.         0.8488, 0.3609,
  31.         0.6683, 0.2536,
  32.         0.6195, 0.2634
  33.     };
  34. city c_t[10];
  35. double dis[10][10];//城市距离矩阵
  36. struct c_gen
  37. {
  38.     string route;//旅行商路径也代表基因编码
  39.     double lenth;//路径长度
  40.     double p;//基因的概率
  41.     c_gen();
  42. };
  43. c_gen::c_gen()
  44. {
  45.     route="";
  46.     lenth=0.0;
  47.     p=0.0;
  48. };
  49. c_gen group[100];//种群
  50. void init_population();//初始化种群
  51. void cal_p();//种群中各个基因概率计算
  52. void select();//选择函数 淘汰33%
  53. void mating();//交配
  54. void aberrance();//变异
  55. void replace_population();//代替旧种群
  56. bool cmp(c_gen a,c_gen b)//自定义排序比较函数
  57. {
  58.     return a.lenth <b.lenth ;
  59. }
  60. void init_population()
  61. {
  62.     for(i=0;i<100;i++)
  63.     {
  64.         int an[10]={2,5,4,9,8,7,0,1,6,3}    ;//给出一个原始祖先
  65.         int ran1=rand()%10;
  66.         int ran2=rand()%10;
  67.         if(ran1==ran2)
  68.         
  69.         {
  70.             ran2=(ran2+rand()%5+1)%10;
  71.         }
  72.         swap(an[ran1],an[ran2]);
  73.         swap(an[(ran1+9)%10],an[(ran1+4)%10]);
  74.         for(j=0;j<10;j++)
  75.         {
  76.             group[i].route+=char(an[j]+'0');
  77.         }
  78.         //产生100个随机的初始祖先 组成种群 
  79.         for(j=0;j<9;j++)
  80.         {
  81.             group[i].lenth +=dis[group[i].route[j]-'0'][group[i].route[j+1]-'0'];
  82.         }
  83.         group[i].lenth +=dis[group[i].route[0]-'0'][group[i].route[9]-'0'];
  84.     }
  85.      
  86.     return ;
  87. }
  88. void cal_p()
  89. {
  90.     double sum=0.0;
  91.     for(i=0;i<100;i++)
  92.     {
  93.         sum+=group[i].lenth ;
  94.     }
  95.     for(i=0;i<100;i++)
  96.     {
  97.         group[i].p=group[i].lenth /sum;
  98.     }
  99. return ;
  100. }
  101. void select()
  102. {
  103.     sort(group,group+100,cmp);//种群按照评价值进行排序
  104.     cout<<"第"<<t<<"代最优品种:  " ;
  105.     for(int temp=0;temp<10;temp++)
  106.     {
  107.         cout<<char(group[0].route [temp]-'0'+'A')<<"-->";
  108.     }
  109.     cout<<char(group[0].route [0]-'0'+'A')<<endl;
  110.     cout<<"路径长度为:   "<<group[0].lenth <<endl;
  111. return ;
  112. }
  113. void mating()//种群规模100 0-65的优秀品种交配 66保留 67-99品种淘汰 被交配的子代代替
  114. {
  115.      
  116. for(i=0;i<33;i++)
  117. {
  118.     int ran1=rand()%10;
  119.     int ran2=rand()%10;
  120.     if(ran1==ran2)
  121.     {
  122.         ran2=(ran2+2)%10;
  123.     }
  124.     char c1=group[i*2].route [ran1];
  125.     char c2=group[i*2].route [ran2];    
  126.     //偶数基因中随机选出2段染色体然后从奇数基因中除去这2段染色体 再将这2段随机插入产生子代
  127.     string t=group[i*2+1].route ;
  128.     int t1,t2;
  129.     int temp;
  130.     bool k1=false;
  131.     bool k2=false;
  132.     for(temp=0;temp<10;temp++)
  133.     {   
  134.         if(t[temp]==c1)
  135.         {
  136.         t.erase ( temp,1);
  137.          
  138.         }
  139.     }
  140.     for(temp=0;temp<9;temp++)
  141.     {   
  142.         if(t[temp]==c2)
  143.         {
  144.         t.erase ( temp,1);
  145.          
  146.         }
  147.     }
  148.     int ran3=rand()%8;
  149.     t.insert (t.begin ()+ran3,c1);
  150.     t.insert (t.begin ()+(ran3+rand())%8,c2);   
  151.     group[67+i].route =t;//子代产生 加入种群
  152. }
  153. return ;
  154. }
  155. void aberrance()
  156. {
  157.     int ran1=rand()%100;
  158.     int ran2=rand()%10;
  159.     int ran3=rand()%10;
  160.     if(ran2==ran3)
  161.     {
  162.     ran3=(ran3+rand()%5+1)%10;
  163.     }
  164.     swap(group[ran1].route [ran2],group[ran1].route [ran3]);
  165.     //随机选出一段基因,然后随机交换2个染色体位置 产生变异
  166. return ;
  167. }
  168. void replace_population()
  169. {
  170.     for(i=0;i<100;i++)
  171.     {
  172.         group[i].lenth =0.0;
  173.     for(j=0;j<9;j++)
  174.         {
  175.             
  176.             group[i].lenth +=dis[group[i].route[j]-'0'][group[i].route[j+1]-'0'];
  177.         }
  178.         group[i].lenth +=dis[group[i].route[0]-'0'][group[i].route[9]-'0'];
  179.     }
  180.     //新种群的评价值重新计算,代替原种群
  181. }
  182. int main()
  183. {
  184.         for(i=0;i<10;i++)
  185.         {
  186.             c_t[i].x=pos[i*2];
  187.             c_t[i].y=pos[i*2+1];
  188.         }//城市节点初始化
  189.         memset(dis,0.0,sizeof(dis));
  190.         for(i=0;i<10;i++)
  191.             for(j=0;j<10;j++)
  192.             {
  193.                 dis[i][j]=sqrt(pow((c_t[i].x -c_t[j].x),2) +pow((c_t[i].y-c_t[j].y),2)) ; 
  194.             }
  195.         //距离矩阵初始化
  196.     init_population();//种群初始化
  197. //遗传算法主体,经过50代的最优解完全符合最优解的条件
  198.     for(t=0;t<50;t++)
  199.     {
  200.             select();
  201.             mating();
  202.             aberrance();
  203.             replace_population();
  204.              
  205.     }
  206. return 0;
  207. }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
简单的遗传算法,计算函数最值. function ga_main() % 遗传算法程序 % n-- 种群规模% ger-- 迭代次数% pc--- 交叉概率% pm-- 变异概率 % v-- 初始种群(规模为n)% f-- 目标函数值% fit-- 适应度向量 % vx-- 最优适应度值向量% vmfit-- 平均适应度值向量 clear all; close all; clc;%清屏 tic;%计时器开始计时 n=20;ger=100;pc=0.65;pm=0.05;%初始化参数 %以上为经验值,可以更改。 % 生成初始种群 v=init_population(n,22); %得到初始种群,22串长,生成20*22的0-1矩阵 [N,L]=size(v); %得到初始规模行,列 disp(sprintf('Number of generations:%d',ger)); disp(sprintf('Population size:%d',N)); disp(sprintf('Crossover probability:%.3f',pc)); disp(sprintf('Mutation probability:%.3f',pm)); %sprintf可以控制输出格式 % 待优化问题 xmin=0;xmax=9; %变量X范围 f='x+10*sin(x.*5)+7*cos(x.*4)'; % 计算适应度,并画出初始种群图形 x=decode(v(:,1:22),xmin,xmax);"位二进制换成十进制,%冒号表示对所有行进行操作。 fit=eval(f);%eval转化成数值型的 %计算适应度 figure(1);%打开第一个窗口 fplot(f,[xmin,xmax]);%隐函数画图 grid on;hold on; plot(x,fit,'k*');%作图,画初始种群的适应度图像 title('(a)染色体的初始位置');%标题 xlabel('x');ylabel('f(x)');%标记轴 % 迭代前的初始化 vmfit=[];%平均适应度 vx=[]; %最优适应度 it=1; % 迭代计数器 % 开始进化 while it<=ger %迭代次数 0代 %Reproduction(Bi-classist Selection) vtemp=roulette(v,fit);%复制算子 %Crossover v=crossover(vtemp,pc);%交叉算子 %Mutation变异算子 M=rand(N,L)<=pm;%这里的作用找到比0.05小的分量 %M(1,:)=zeros(1,L); v=v-2.*(v.*M)+M;%两个0-1矩阵相乘后M是1的地方V就不变,再乘以2. NICE!!确实好!!!把M中为1的位置上的地方的值变反 %这里是点乘 %变异 %Results x=decode(v(:,1:22),xmin,xmax);%解码,求目标函数值 fit=eval(f); %计算数值 [sol,indb]=max(fit);% 每次迭代中最优目标函数值,包括位置 v(1,:)=v(indb,:); %用最大值代替 fit_mean=mean(fit); % 每次迭代中目标函数值的平均值。mean求均值 vx=[vx sol]; %最优适应度值 vmfit=[vmfit fit_mean];%适应度均值 it=it+1; %迭代次数计数器增加 end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值