模拟退火算法 解决旅行商(TSP)问题

  1. #include<iostream>
  2. #include<string>
  3. #include<math.h>
  4. #include<cstdlib>
  5. using namespace std;
  6. // ******************************************************************************************
  7. /*
  8.         模拟退火算法解决10城市的TSP问题
  9.     (1) 初始化:初始温度T(充分大),初始解状态S(是算法迭代的起点), 每个T值的迭代次数L 
  10.     (2) 对k=1,……,L做第(3)至第6步: 
  11.   (3) 产生新解S′ 
  12.   (4) 计算增量Δt′=C(S′)-C(S),其中C(S)为评价函数 
  13.   (5) 若Δt′<0则接受S′作为新的当前解,否则以概率exp(-Δt′/T)接受S′作为新的当前解. 
  14.   (6) 如果满足终止条件则输出当前解作为最优解,结束程序。 
  15.        终止条件通常取为连续若干个新解都没有被接受时终止算法。 
  16.   (7) T逐渐减少,且T->0,然后转第2步。
  17.                                                     baixzh  SYSU 2008-11-19 
  18. */  
  19. // ******************************************************************************************
  20.     int i;int j;
  21.     struct city//城市节点 坐标表示
  22.     {
  23.         double x;
  24.         double y;
  25.         city();
  26.          
  27.     };
  28.     city::city ()
  29.     {
  30.         x=0.0;
  31.         y=0.0;
  32.     }
  33.      
  34.     city c_t[10];//10个城市的tsp问题
  35.     double pos[20]=//初始城市坐标数据
  36.     {
  37.         0.400,  0.4439,//代表x,y
  38.         0.2439, 0.1463,
  39.         0.1707, 0.2293,
  40.         0.2293, 0.7610,
  41.         0.5171, 0.9414,
  42.         0.8732, 0.6536,
  43.         0.6878, 0.5219,
  44.         0.8488, 0.3609,
  45.         0.6683, 0.2536,
  46.         0.6195, 0.2634
  47.     };
  48.     double dis[10][10];//城市距离矩阵
  49.      
  50.     int state[10]={7,8,9,1,5,0,6,2,4,3};//给出初始路径
  51.     int s1[10],s2[10];//s1原始路径 s2为s1生成的临近路径
  52.     double result1,result2;//原路径长度 临近路径长度
  53.     void xch(int state[10])//生成临近路径并且计算长度,保存原路径
  54.     {   
  55.         result1=result2=0.0;
  56.         for(i=0;i<10;i++)
  57.         {
  58.             s1[i]=s2[i]=state[i];
  59.         }
  60.         for(i=0;i<9;i++)
  61.         {
  62.             result1=result1+dis[s1[i]][s1[i+1]];
  63.         }
  64.         result1=result1+dis[s1[0]][s1[9]];
  65.         //s1以前的s2改变后的
  66.         int k1=rand()%10;int k2=rand()%10;
  67.         if(k1==k2)
  68.         {
  69.             k2=(k1+2)%10;
  70.         }
  71.         swap(s2[k1],s2[k2]);
  72.         for(i=0;i<9;i++)
  73.         {
  74.             result2=result2+dis[s2[i]][s2[i+1]];
  75.         
  76.         }
  77.         result2=result2+dis[s2[0]][s2[9]];
  78.         //最后要返回出发城市
  79.     }
  80.      
  81.     int main()
  82.     {   
  83.         for(i=0;i<10;i++)
  84.         {
  85.             c_t[i].x =pos[2*i];
  86.             c_t[i].y =pos[2*i+1];
  87.         }
  88.         //城市节点初始化
  89.         memset(dis,0.0,sizeof(dis));
  90.         for(i=0;i<10;i++)
  91.             for(j=0;j<10;j++)
  92.             {
  93.                          dis[i][j]=sqrt(pow((c_t[i].x -c_t[j].x),2) +pow((c_t[i].y-c_t[j].y),2)) ; 
  94.             }
  95.         //距离矩阵初始化
  96.         double tmp=1000.0;
  97.         int loop_1=1;//外循环计数
  98.         int loop_2=0;//内循环计数
  99.         while(1)
  100.         {       
  101.             loop_2=0;
  102.             while(1)
  103.             {   
  104.                 if(loop_2>tmp*3)//内循环结束条件
  105.                 {
  106.                     break;
  107.                 }
  108.                 xch(state);
  109.                 loop_2++;
  110.                 if(result2<result1)
  111.                 {
  112.                     for(j=0;j<10;j++)
  113.                     {
  114.                         state[j]=s2[j];
  115.                     }
  116.                 //如果生成路径长度小于原始路径则替换             
  117.                 }
  118.                 else
  119.                 {
  120.                     double d=(result2-result1);
  121.                     double e=exp(-d/(0.0001*tmp));
  122.                     double r=rand()%100;
  123.                     double k=r/100.0;
  124.                     if(e>k)
  125.                     {
  126.                         for(j=0;j<10;j++)
  127.                     {
  128.                         state[j]=s2[j];
  129.                     }
  130.                     //如果生成路径长度大于初始路径长度//但是概率e>rand(0,1)也接受新路径
  131.                     }
  132.                     else
  133.                     {
  134.                     for(j=0;j<10;j++)
  135.                     {
  136.                         state[j]=s1[j];
  137.                     }
  138.                     }//否则不做替换           
  139.                 }
  140.             }
  141.             //输出每次内部循环结束后的路径
  142.             xch(state);
  143.             cout<<"第"<<loop_1<<"次降温 "<<"温度为"<<tmp<<"     结果为    :"<<endl;
  144.             cout<<result1<<"    ";
  145.             for(j=0;j<9;j++)
  146.             {
  147.                 cout<<char('A'+state[j])<<"--";
  148.             }
  149.             cout<<char('A'+state[9])<<endl;
  150.             tmp=tmp*0.95;//温度按照比例下降
  151.             loop_1++;
  152.             if(tmp<1)//外循环结束条件
  153.             {
  154.                 break;
  155.             }
  156.             
  157.         } 
  158.      
  159.         return 0;
  160.     }
  161.      
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值