您的位置:首页 > 编程语言 > Java开发

蚁群算法解决TSP问题的JAVA实现(一)

2015-03-18 12:33 393 查看

1.算法背景

关于基本的蚁群算法及TSP问题本文不做描述,可参考百度百科做简单了解:

蚁群算法

TSP问题

本程序主要实现了蚁群算法及其应用[1] 蚁群算法及其应用^{[1]} P26–2.3蚁周系统模型中所描述的算法,并依JAVA语言特性及问题规模做了小幅度修改。在该书的第二章还描述了另外两种基本的蚁群系统,蚁量系统蚁密系统,因为普遍认为蚁周系统要优于另外两种系统,故本程序将实现蚁周系统

2.数学模型

2.1.参数描述

城市规模为n,即有n座城市,从0 ~ n - 1对其进行编号;若i,j为其中的任意两个城市的编号,则有 i,j >= 0 && i , j <= n - 1。

dijd_{ij}:两城市i和j之间的距离;将任意两城市看作两个点,则此距离为二维平面上这两点间的直线距离;设定多个城市不可重叠在同一个点上,因此当i = j时,dij=0d_{ij}=0,但此时无意义;当i != j时,dij>0d_{ij}>0。又规定两城市间的距离向量是对称的,即有dij=djid_{ij} = d_{ji}。

ηij\eta_{ij}:由城市i转移到城市j的启发程度,即环境因素本身对蚂蚁选择判断的影响,这个值在蚁群系统的运行中不改变。在本算法中ηij=1/dij\eta_{ij} = 1 / d_{ij},即i,j两城市的距离越短对蚂蚁选择的吸引力越大。又因dij=djid_{ij} = d_{ji},则同样也有ηij=ηji\eta_{ij} = \eta_{ji}。

时刻t,为计算机模拟的实际环境时间;该时刻是离散而非连续的;从0时刻起,最小离散单位为1,即时刻为0,1,2,3,4,5···通常在1个时刻以内会发生蚂蚁移动一步这类的原子事件。

bi(t)b_i(t):t时刻位于城市i的蚂蚁数目;有m=∑n−1i=0bi(t)m = \sum_{i=0}^{n-1}b_i(t)。

τij(t)\tau_{ij}(t):城市i,j之间t时刻时边上的信息素轨迹强度,初始t=0时刻时,设置一个初始常量τij(t)=C\tau_{ij}(t) = C,其中C∈NC \in N。τij(t)∈N\tau_{ij}(t) \in N;当i=j时无实际意义;又因边具有对称的特性,故τij(t)=τji(t)\tau_{ij}(t) = \tau_{ji}(t)

Δτkij(t,t+Δt)\Delta\tau_{ij}^k(t,t+\Delta t):在t时刻到t+Δtt+\Delta t时刻这Δt\Delta t的时间内,蚂蚁k在(i,j)城市间路段上产生的信息素量。同样,Δτkij(t,t+Δt)∈N\Delta\tau_{ij}^k(t,t+\Delta t) \in N且Δτkij(t,t+Δt)=Δτkji(t,t+Δt)\Delta\tau_{ij}^k(t,t+\Delta t) = \Delta\tau_{ji}^k(t,t+\Delta t)。

Δτij(t,t+Δt)\Delta\tau_{ij}(t,t+\Delta t):在t时刻到t+Δtt+\Delta t时刻这Δt\Delta t的时间内,(i,j)城市间路段的信息素增量。有Δτij(t,t+Δt)=∑m−1k=0Δτkij(t,t+Δt)\Delta\tau_{ij}(t,t+\Delta t) = \sum_{k=0}^{m-1} \Delta\tau_{ij}^k(t,t+\Delta t)。同样,Δτij(t,t+Δt)∈N\Delta\tau_{ij}(t,t+\Delta t) \in N且Δτij(t,t+Δt)=Δτji(t,t+Δt)\Delta\tau_{ij}(t,t+\Delta t) = \Delta\tau_{ji}(t,t+\Delta t)。

τij(t+Δt)=ρ⋅τij(t)+Δτij(t,t+Δt)\tau_{ij}(t + \Delta t) = \rho·\tau_{ij}(t) + \Delta\tau_{ij}(t,t+\Delta t),其中ρ∈[0,1]\rho \in [0,1]为τij(t)\tau_{ij}(t)在刷新信息素时的保留百分比;若为0则全部挥发,若为1则全部保留。

蚁群规模为m,即蚁群中有m只蚂蚁,从0 ~ m - 1对其进行编号;k为其中的任意1只蚂蚁的编号,则有 k >= 0 && k <= m - 1。

tabuktabu_k:蚂蚁k的禁忌表;初始时为空。每当蚂蚁到达一个城市都将该城市放到禁忌表中。因为tSP问题特性规定了除初始城市外每个城市都仅访问1次,故禁忌表长度固定为城市规模n;当禁忌表填满后,禁忌表中的城市顺序组成的路径即为TSP问题的一个解。

LkL_k:第k只蚂蚁在求得某解后所走过的路径长度;注意*该长度必须包括最后一个到访的城市到初始城市的距离,因为TSP问题要求回到初始城市*,Lk>0L_k > 0。

QQ:蚂蚁在求得一个解后在其路径上播撒的信息素总量。这是一个常量值且Q∈N+Q \in N^+

蚂蚁的运动速度与路径的实际长度无关;固定每个1个单位时间内可从某城市到达任意另一个城市。

Δτkij(t,t+Δt)=Q/Lk,如果蚂蚁k在某次循环中经过路径i,j
\Delta\tau_{ij}^k(t,t+\Delta t) = Q / L_k ,如果蚂蚁k在某次循环中经过路径i,j

Δτkij(t,t+Δt)=0,否则
\Delta\tau_{ij}^k(t,t+\Delta t) = 0 ,否则

因为(i,j)与(j,i)是同一条道路,故只要蚂蚁经过了(i,j)则Δτkij(t,t+Δt)\Delta\tau_{ij}^k(t,t+\Delta t) 与Δτkji(t,t+Δt)\Delta\tau_{ji}^k(t,t+\Delta t) 都应该加上该蚂蚁释放的信息素,这样才能确保对称

allowedkallowed_k:蚂蚁k下一步允许到达的城市。即所有不在蚂蚁禁忌表tabuktabu_k中的其他城市。

Pkij(t)=ταij(t)ηβij∑s∈allowedkταis(t)ηβis,j∈allowedk
P_{ij}^k(t) = \frac{\tau_{ij}^\alpha(t)\eta_{ij}^\beta}{\sum_{s \in allowed_k}\tau_{is}^\alpha(t)\eta_{is}^\beta},j \in allowed_k

Pkij(t)=0,otherwise
P_{ij}^k(t) = 0,otherwise

Pkij(t)P_{ij}^k(t)表示若t时刻蚂蚁k位于城市i,则它到达城市j的概率; Pkij(t)∈[0,1]P_{ij}^k(t) \in [0,1]且Pkij(t)=Pkji(t)P_{ij}^k(t) = P_{ji}^k(t)。α\alpha和β\beta是两个常量,分别控制信息素信息及环境因素信息对蚂蚁选择城市的影响程度

bestWaybestWay:每轮找到的最优路径组成的数组;从当轮蚂蚁填满的禁忌表中筛选。标准为走过的长度LkL_k最短。

NcmaxN_{cmax}:常量,最大求解循环次数,当到达该次数后算法停止。Ncmax∈N+N_{cmax} \in N^+。

2.2.算法流程

2.2.1.初始化

初始化城市,及各常量参数;初始时刻为t=0

2.2.2.循环

【循环层1】共循环NcmaxN_{cmax}轮,每轮循环用时(n-1)个单位时间,发生如下事件:

本轮刚开始的时刻为t时刻,生成一个规模为m的蚁群,将m只蚂蚁随机放置到n个城市中,并将蚂蚁们的初始城市放入其禁忌表中。该操作不耗费时间。

【循环层1-1】循环n-1次,该循环结束后每只蚂蚁的禁忌表都将被填满,每只蚂蚁都访问了所有城市1次且仅一次,时间流逝了n-1个单位时间,每次:

1.时间t=t+1,表示每次循环时间都流逝了1个单位时间。

2.【循环层1-1-1】循环m次,这m次循环是在一个单位时间内同时并行发生的,每只蚂蚁都做如下动作:

蚂蚁依Pkij(t)P_{ij}^k(t)到达一座新的城市,同时将新的城市加入自己的禁忌表。

【循环层1-2】循环m次,遍历所有蚂蚁的禁忌表。

得到每只蚂蚁的LkL_k。

得到本轮的最优路径bestWaybestWay

将蚂蚁禁忌表中走过的路径播洒上信息素。Δt=n−1\Delta t = n - 1

将本轮的最优路径bestWaybestWay与全局的最优路径对比,若更优秀,则替换。

消灭当前的蚁群(杀死所有蚂蚁),然后休整一个单位时间,t=t+1。

2.2.3.统计结果

输出最终的全局最优路径,即为本算法得出的解。

2.3.简单的例子

为了便于理解,设计一个简单的小栗子。假如共有n=3座城市,蚁群中有m=1只蚂蚁,共进行3轮实验,则3轮中该蚂蚁的移动路线可能为:

时刻t所在城市编号所属轮数编号
000
110
220
321
411
501
612
722
802
以第2轮实验为例,禁忌表中经过城市为2-1-0;则将更新(2,1)=(1,2);(1,0)=(0,1)路段的信息素强度。【因为路段是对称的,故(i,j)及(j,i)都应更新】

详细代码设计将在后续博文给出。

参考文献

[1] 李世勇等.蚁群算法及其应用.哈尔滨.哈尔滨工业大学出版社.2004
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: