利用HTML5 Canvas和Javascript实现的蚁群算法求解TSP问题演示

奇葩方法,看着挺酷的,忍不住转载。。

HTML5提供了Canvas对象,为绘图应用提供了便利.

Javascript可运行于浏览器中, 而不需要安装特定的编译器;

基于HTML5和Javascript语言, 可随时编写应用, 为算法测试带来便利.

针对TSP问题, 编写了Ant colony algorithm, 用于演示该算法, tsp_ant_colony_algorithm.html代码如下:

http://blog.csdn.net/miscclp/article/details/41169837 原文链接

[html]  view plain copy
  1. <html>  
  2. <head>  
  3.  <meta charset = "utf-8" / >   
  4. <title>TSP_demo</title>  
  5. </head>  
  6. <body>  
  7. <div id="outText">  
  8. </div>  
  9. <canvas id="canvas" height="550px" width="1024px">  
  10. </canvas>  
  11. <script type="text/javascript">  
  12. //计时开始  
  13. t1 = new Date();            //创建"then"这个日期/时间对像  
  14. t1.setTime(t1.getTime());   //为这个对象赋值  
  15.   
  16. var canvas = document.getElementById("canvas");  
  17. var canvasWidth = canvas.width;  
  18. var canvasHeight = canvas.height;  
  19. var context = canvas.getContext("2d");  
  20.   
  21. var N = 30;   //城市数量  
  22. var M = 120;   //蚂蚁数量  
  23.   
  24. var inittao = 1;   //初始路径激素量   
  25. var tao;   //[N][N];     //N*N矩阵——表示i和j间残留的激素信息量, 初始化为常熟C(各路径相等),以表示激素的挥发  
  26. var yita; //[N][N];      //N*N矩阵——表示i和j间由举例所决定的选择概率矩阵  
  27. var delta_tao; //[N][N]; //一轮循环后增加的信息素  
  28. var distant; //[N][N];   //所有城市间的距离  
  29. var tabu; //[M][N];         //禁忌表  
  30. var route; //[M][N];        //M只蚂蚁所走过的路径  
  31. var solution; //[M];     //对M只蚂蚁所走过路径的适应度评价值  
  32. var BestRoute; //[N];       //最忌路径  
  33. var BestSolution = 10000000000;   //设置的极限最大路径  
  34. var alfa, beta, rou, Q;        //路径激素更新数量  
  35. var NcMax;                        //蚁群最大迭代次数  
  36.   
  37. function initMat(M, N, val) {  
  38.   var x = new Array();  
  39.   for(var i = 0; i < M; i++) {  
  40.     x[i] = new Array();  
  41.     for(var j = 0; j < N; j++)  
  42.         x[i].push(val);  
  43.   }  
  44.   return x;  
  45. }  
  46.   
  47. function initAllMats() {  
  48.     tao = initMat(N, N, 0);  
  49.     yita = initMat(N, N, 0);  
  50.     delta_tao = initMat(N, N, 0);  
  51.     distant = initMat(N, N, 0);  
  52.     tabu = initMat(M, N, 0);  
  53.     route = initMat(M, N, -1);  
  54.       
  55.     solution = new Array();  
  56.     for(var i = 0; i < M; i++)  
  57.         solution[i] = 0;  
  58.           
  59.     BestRoute = new Array();  
  60.     for(var i = 0; i < N; i++)  
  61.         BestRoute[i] = -1;  
  62. }  
  63.   
  64. //初始化城市的位置  
  65. function InCityXY(x, y)  
  66. {   
  67.     for(var i = 0; i < N; i++) {  
  68.         x[i] = (Math.random() * 32767) % 980 + 20;  
  69.         y[i] = (Math.random() * 32767) % 420 + 20;  
  70.     }  
  71. }  
  72.   
  73. //初始化算法参数  
  74. function initparameter()   
  75. {   
  76.     alfa = 1;   //积累的激素调节因子作用系数  
  77.     beta = 5;   //启发性调节因子作用系数  
  78.     rou = 0.9;    
  79.     Q = 100;    //常量  
  80.     NcMax = 200; //群蚂蚁进化代数  
  81. }   
  82.   
  83. //取得某个路径的长度  
  84. function EvalueSolution(a)   
  85. {   
  86.     var dist = 0;   
  87.     for(var i = 0; i < N-1; i++)  
  88.         dist += distant[a[i]][a[i+1]];   
  89.     dist += distant[a[N-1]][a[0]];   
  90.     return dist;   
  91. }   
  92.   
  93. function drawCities(x, y) {  
  94.     for(var i = 0; i < N; i++) {  
  95.         context.beginPath();  
  96.   
  97.         context.fillStyle = "blue";  
  98.         context.strokeStyle = "blue";  
  99.         context.lineWidth = 1;  
  100.         context.font = "normal 16px Arial";  
  101.   
  102.         context.arc(x[i], y[i], 3, (Math.PI / 180) * 0, (Math.PI / 180) * 360, false);  
  103.         context.fill();  
  104.         context.stroke();  
  105.         context.closePath();  
  106. /*  
  107.         context.fillStyle = "white";  
  108.         context.textAlign = "center";  
  109.         context.textBaseline = "middle";  
  110.         context.fillText(String(i), x[i], y[i]);  
  111. */  
  112.     }  
  113. }  
  114.       
  115. function drawPath(x1, y1, x2, y2, color, width) {  
  116.     context.beginPath();  
  117.     context.fillStyle = color;  
  118.     context.strokeStyle = color;  
  119.     context.lineWidth = width;  
  120.     context.moveTo(x1, y1);  
  121.     context.lineTo(x2, y2);  
  122.     context.stroke();  
  123. }  
  124.   
  125. //主函数  
  126. function ACA_TSP() {  
  127.     var NC = 0;   
  128.     //初始化算法参数  
  129.     initparameter();   
  130.       
  131.     //初始化城市的位置  
  132.     var x = new Array();  
  133.     var y = new Array();  
  134.     for(var i = 0; i < N; i++) {  
  135.         x.push(0);  
  136.         y.push(0);  
  137.     }  
  138.     //初始化城市位置  
  139.     InCityXY( x, y );   
  140.   
  141.     //计算任意两城市间的距离  
  142.     for(var i=0;i<N;i++)   
  143.         for(var j=i+1;j<N;j++)   
  144.         {   
  145.             distant[j][i] = Math.sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));   
  146.             distant[i][j] = distant[j][i];   
  147.         }   
  148.     // calculate the heuristic parameters   
  149.     var i, j, k;  
  150.     //初始化任意两点间的选择可能性程度=1-p  
  151.     //若i==j,则p=1  
  152.     //否则,p=100/distant[i][j]  
  153.     for(i=0;i<N;i++)   
  154.         for(j=0;j<N;j++)   
  155.         {   
  156.             tao[i][j] = inittao;   
  157.             if(j != i)   
  158.                 yita[i][j] = 100/distant[i][j];    //值越大,i到j被选择的路径概率越大; 或者说,i和j距离越近,被选择的概率越大  
  159.         }   
  160.     //初始化M个蚂蚁走完所有城市(N)的路径  
  161.     //-1表示第k只蚂蚁尚没有从当前位置走向i城市  
  162.     /*  
  163.     for(k=0;k<M;k++)   
  164.         for(i=0;i<N;i++)   
  165.             route[k][i] =- 1;   
  166.     */  
  167.     //初始化所有蚂蚁的禁忌表  
  168.     for(k=0;k<M;k++)   
  169.     {   
  170.         route[k][0] = k % N;     //随机置放蚂蚁的第一站城市点---此代码实际上没有随机摆放  
  171.         tabu[k][route[k][0]] = 1;  //设置禁忌表的已访问过的城市为1  
  172.     }   
  173.     //所有蚂蚁行走NcMax趟  
  174.     do {   
  175.         var s = 1;   
  176.         var partsum;   
  177.         var pper;   
  178.         var drand;   
  179.   
  180.         //s循环N次,让每只蚂蚁走N步,走完全程  
  181.         while( s < N)   
  182.         {   
  183.             for(k=0;k<M;k++)   
  184.             {   
  185.                 var jrand= (Math.random() * 32767) % 3000;   
  186.                 drandjrand / 3001.0;   
  187.                 partsum = 0;   
  188.                 pper = 0;   
  189.                 for(j=0;j<N;j++)   
  190.                 {   
  191.                     if(tabu[k][j]==0)   
  192.                         partsum += Math.pow(tao[route[k][s-1]][j],alfa) * Math.pow(yita[route[k][s-1]][j],beta);   
  193.                 }   
  194.                 for(j=0;j<N;j++)   
  195.                 {   
  196.                     if(tabu[k][j]==0)   
  197.                         pper += Math.pow(tao[route[k][s-1]][j],alfa) * Math.pow(yita[route[k][s-1]][j],beta)/partsum;   
  198.                     if(pper > drand)   
  199.                         break;   
  200.                 }   
  201.                 tabu[k][j]=1;   
  202.                 route[k][s]=j;   
  203.             }   
  204.             s++;   
  205.         }   
  206.         // the pheromone is updated   
  207.         for(i=0;i<N;i++)   
  208.             for(var j=0;j<N;j++)   
  209.                 delta_tao[i][j]=0;   
  210.         //记录最短路径及其长度  
  211.         for(k=0;k<M;k++)   
  212.         {   
  213.             solution[k] = EvalueSolution(route[k]);   
  214.             if(solution[k] < BestSolution)   
  215.             {   
  216.                 BestSolution = solution[k];   
  217.                 for(s=0; s<N; s++)   
  218.                     BestRoute[s]=route[k][s];   
  219.             }   
  220.         }   
  221.         //根据上一批次(M个蚂蚁)所求路径的长度信息,更新从i到j的选择概率  
  222.         for(k=0;k<M;k++)   
  223.         {   
  224.             for(s=0;s<N-1;s++)   
  225.                 delta_tao[route[k][s]][route[k][s+1]] += Q/solution[k];   
  226.             delta_tao[route[k][N-1]][route[k][0]] += Q/solution[k];   
  227.         }   
  228.         //计算NxN个节点间的转移概率,并设置最大与最小值  
  229.         for(i=0;i<N;i++)   
  230.             for(var j=0;j<N;j++)   
  231.             {   
  232.                 tao[i][j]=rou*tao[i][j]+delta_tao[i][j];   
  233.                 if(tao[i][j] < 0.00001)   
  234.                     tao[i][j] = 0.00001;   
  235.                 if(tao[i][j] > 20)   
  236.                     tao[i][j] = 20;   
  237.             }   
  238.         //重新设置所有蚂蚁的禁忌表和路径信息  
  239.         for(k=0;k<M;k++)   
  240.             for(var j=1;j<N;j++)   
  241.             {   
  242.                 tabu[k][route[k][j]]=0;   
  243.                 route[k][j]=-1;   
  244.             }   
  245.         NC++;   
  246.     } while(NC < NcMax);   
  247.     //output the calculating outs   
  248.     /*  
  249.     print("*针对旅行商问题的蚂蚁克隆算法*");   
  250.     print("初始参数:");   
  251.     print("alfa=" + alfa + "beta=" + beta + "rou=" + rou + "Q=" + Q);   
  252.     print("蚁群探索循环次数:" + NcMax);  
  253.     print("最短路径是:" + BestSolution);  
  254.     print("最佳路径是:");   
  255.     */  
  256.     for(i = 0; i < N; i++) {  
  257.         if (i == N - 1)  
  258.             j = 0;  
  259.         else  
  260.             j = i + 1;  
  261.         var nodeA = BestRoute[i];  
  262.         var nodeB = BestRoute[j];  
  263.         var x1 = x[nodeA];  
  264.         var y1 = y[nodeA];  
  265.         var x2 = x[nodeB];  
  266.         var y2 = y[nodeB];  
  267.         drawPath(x1, y1, x2, y2, "black", 2);  
  268.     }  
  269.     drawCities(x, y);  
  270.       
  271.       
  272.     var out = document.getElementById("outText");  
  273.     out.innerHTML = "<h1>蚂蚁克隆算法求解旅行商问题: </h1>最佳路径:<br/>";  
  274.     for(i=0;i<N;i++)   
  275.         out.innerHTML = out.innerHTML + String(BestRoute[i]) + " ";  
  276.     out.innerHTML = out.innerHTML + "<br/>最短路径长度:<br/>" + BestSolution;  
  277. }  
  278.   
  279. //调用上述函数  
  280. initAllMats();  
  281. ACA_TSP();  
  282.   
  283. //结束后,取得现在时间, 并计算时间差  
  284. t2 = new Date();            //创建"then"这个日期/时间对像  
  285. var ms = t2.getTime() - t1.getTime();  
  286. var out = document.getElementById("outText");  
  287. out.innerHTML = out.innerHTML + "<br/>用时(毫秒):<br/>" + ms;  
  288. </script>  
  289. </body>  
  290. </html>  

刷新该页面, 可随机产生不同的城市点, 并计算最短路径.

实例效果如下:


需要说明的是, 算法仍需改善, 在有些其情况下,无法保障总能获得最短路径.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值