首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

ACS蚁群算法求解对称TSP旅行商问题的JavaScript实现(2)

ACS蚁群算法求解对称TSP旅行商问题的JavaScript实现(2)

(2) ACS解决TSP问题      在本文中,使用ACS解决对称TSP问题,具体的解题步骤如下:
      A.初始化全局参数      n:城市数n,
      m:蚂蚁只数m (用随机数取n^0.5 ~ n/2之间的值),
      p:信息素蒸发系数p=0.7,
      NC,NC_max:初始外循环次数NC=1,最大循环次数NC_max=60,
      D:用坐标计算两两城市之间的距离矩阵D,
      T:初始城市路线之间的信息素浓度矩阵T(初始默认相等,均为1/(n*(n-1)),即和为1),
      E:每只蚂蚁前进时的城市路线信息素浓度矩阵E(每一轮均为当时的T,假设每一轮的蚂蚁之间相互影响极小,忽略不计,留下的信息素主要对后面的蚂蚁起作用),
      last,lastRoute:用于存储当前最优路线的总长度last和最优过程lastRoute。
      B.外循环      循环变量为轮数NC。每一次外循环均初始化当前轮数当前蚂蚁i的行走路径。每一次内循环结束之后计算当前NC下每只蚂蚁的总行走长度sAll,记录每只蚂蚁的行走过程并由此得到当前最短的行走总长度last和路线lastRoute,之后按照公式1相对增强当前最佳路线的信息素,挥发其它路线信息素,再进入下一轮。
      C.内循环      对于每一只蚂蚁i,记录它们的需要访问城市列表route。
默认从城市0出发(从哪儿出发其实都一样),按照到其它城市信息素的比例随机选择下一个城市。具体做法为求出下一个城市到当前城市的距离比上总的距离之和,然后逐个累加,于是求得比例区间[0 ~ p1 , p1 ~ p1 + p2 , p1 + p2 ~ p1 + p2 + p3......1]。用Math.random函数取0~1之间的随机值判断在哪个区间,则下一步走到对应的城市。然后将route中对应的城市置0,并将已选城市与原始城市之间的距离置0,重新计算比例区间的时候即可不影响,当route中所有的数值之和为0时说明除了初始城市全部都访问了,最后访问初始城市0,一只蚂蚁即完成使命。
3 具体实现      根据以上算法过程,可以写出程序如下:
(1)  Functions.js      自定义工具函数,减少全局对象,尽可能代码重用。
      其中:
      minAll(arr): 返回一维数组arr中的最小值
      all(arr) :一维数组arr求和
      nextStep(x,E): 根据当前城市x和所有路径信息素的浓度矩阵E随机确定下一座城市,类似转盘法。详细算法见上面2.(2).C。
      sum(x,E) :配合nextStep实现转盘效果
      new2Arr(arr,x): 将undefined类型的新建arr转化为二维数组,一般用来初始化
      getAntNum(x) :通过城市数量得到最佳蚂蚁数量

      getType(o) , extend(destination,source): 实现对象的深复制,尤其针对多维数组(一般情况下的一维的用slice或者concat就行),见参考文献[6]。

(2)  AntSystem.js      ACS蚁群算法的具体实现,封装于AntSystem(C)中,便于调用。输入城市坐标矩阵C,输入最优路径总长度last和最优路径lastRoute。
(3)  Action.js

      利用jquery.js工具库实现自定义数据输入和最终结果展现。有部分数据类型判断。(基于关注算法本身的准则,仅对输入的蚂蚁数量n有一定的判断和提示)

(4)  Jquery-1.11.0.js

      一种流行的js库,用于js快速兼容开发


4 算法测试

      点击default.html 按照提示输入数据一步步提交即可。兼容IE8.0+,firefox,chrome等浏览器。

      运行过程截图:

  • 输入合适数目后点击确认弹出坐标矩阵输入窗口


      2.输入坐标矩阵点击确认得到最终的结果

      输入为(0,0), (0,1), (0,2), (0,3), (0,4), (1,0), (1,1), (1,2), (1,3), (2,2), (2,3), (2,4), (3,3), (3,4)。


      3.在FF的控制台脚本中合适的地方设置断点可以单步查看具体的运行过程(由于具体展示出来过于占据篇幅,全部输出网页显示过于琐细,这儿列一张图)(可以按照需要将每一轮的重要数据抽取出来查看具体变化)



5 分析和总结      本次ACS解决对称TSP问题的javascript实现,相对于经典的ACS,有一些修改的地方:
      1.外循环结束条件只有循环轮数NC<NC_max。不考虑是否已经收敛。
      2.采用参考文献[4]上的推荐挥发系数p值,不是多次数据测量确认。

      Js作为一种弱变量的语言,拥有一些隐性默认的规则:
      1.使用+符号时可能会默认将两边变量的数据类型改为string。参见参考文献[7]。
      2.在函数内部申明变量x时,如果不使用var语句而是直接给变量x赋值会导致变量x变为全局变量,污染全局空间。
      3.函数的参数在函数内部作为局部变量存在,当函数结束时结束(除非使用闭包),不会对外面同名变量产生影响。
      4.对象变量之间使用=号是对象的引用传递,即两个对象指向内存中同一块区域,当一个变量改变对象的属性时,另外一个变量对应的属性也会变。因此,需要用到对象的深复制。对于一维数组使用slice和concat函数,对于多维数组参照参考文献[6]。
继承事业,薪火相传
返回列表