实现论文
《求解旅行商问题的Matlab蚁群仿真研究》
链接:https://pan.baidu.com/s/1scdDvKvUviEVEeQC8fweRg
提取码:k38b
实验目的
蚁群算法是一种新颖的求解复杂优化组合问题的模拟进化算法, 它具有典型的群体智能的特性, 该算法的主要特点是正反馈、分布式计算、鲁棒性和并行性等, 在许多领域都得到了成功应用; 文章首先简述了蚁群的觅食行为及蚂蚁的信息系统, 其次介绍了人工 蚁群算法的基本原理及其主要特点, 介绍了蚁群算法的模型和算法框图, 并用蚁群算法对旅行商问( TravelingSalesman Problem, TSP) 进行了 matl ab 仿真实现 ( 设置蚂蚁个数 31, 启发式因子为 1, 期望启发因子为 5, 信息素的挥发系数为 0 1, 最大迭代次数为 200, 信息素强度系数为 100, 城市个数为 31, 用蚁群算法得出了 31 个城市的 TSP 最短路径和收敛曲线) ; 最后介绍了近年来蚁群算法 及其在组合优化中的应用研究成果, 并对蚁群算法未来的发展方向进行了探讨。
基本思路
自然界蚂蚁能够不依赖视觉辅助, 只依靠信息素和蚂蚁间 共同合作, 便能找出蚁巢与食物间之最短路径。每一只蚂蚁个 体几乎相近, 所残留的信息素也相近, 行进速度相同, 受信息 素的影响也相同。其基本原理是蚂蚁外出觅食时, 会在行经巢 穴与食物间的路径上, 留下一种自然化学物质, 这种物质称为 信息素 ( Pheromo ne) , 而蚂蚁之间就是借助信息素作为沟通 的媒介, 利用此媒介与其他蚂蚁间相互传递讯息。当蚂蚁由巢穴出发寻找食物的过程中, 较短的路径上会累积较多的信息 素, 从而使得后面较晚出发的蚂蚁会依循信息素浓度较重的路 径行走, 最后趋于同一条路径上。 如图 1 所示[ 1] , 蚁群寻找食物时会派出一些蚂蚁分头在四 周游荡, 如果一只蚂蚁找到食物, 它就返回巢穴中通知同伴并 沿途留下信息素作为蚁群前往食物所在地的标记。信息素会逐 渐挥发, 如果 2 只蚂蚁同时找到同一食物, 又采取不同的路线 回到巢中, 那么比较绕弯的一条路上信息素的气味会比较淡, 蚁群将倾向于沿着另一条更近的路线前往食物所在地。
基本流程
为了更好地说明蚁群算法, 引入如下的标记: m 表示群体 中蚂蚁的个数; dij 表示城市 i 和 j 之间的距离, ij 表示 t 时刻 边 ( i, j ) 上残留的信息素; 设ij( 0) = c ( c 为常数) ; ij 为 边 (i, j ) 的能见度因数, 在这里 ij 取 1/ dij 。p kij ( t) 表示在 t 时刻蚂蚁 k 由 i 转移到 j 的概率, 如下式所示[ 4] 。 Pkij (t) = ij ( t)ij ( t) s {允许F}
is ( t)is ( t) , j { 允许 F} 0, 其他 ( 1) 式中, F = { C – tabu ( k) } 为蚂蚁 k 下一步允许选择的城 市; C= ( C1, C2 , , Cn ) 是 n 个城市的集合; tabu ( k ) ( k = 1, 2, , m) 记录蚂蚁 k 目前己经走过的城市; s 为F 中任 意的城市; 为信息启发式因子; 为期望启发因子, 用 表 示信息素的挥发系数, 1- 为信息素残留系数, ( 0, 1) 。 在 t+ n 时刻, 在路径 ( i, j ) 上信息量可按如下规则调整: ij ( t + n) = ( 1- ) * ij ( t) + ij (t) , ( 0, 1) ( 2) ij ( t) = m k = 1ij k ( t) ( 3) 用 kij ( t) 表示第 k 只蚂蚁在本次循环中留在路径上的 信息素增量, 则 m 只蚂蚁在本次循环中留在路径上的总的信息 量就表示为 ij ( t) 。确定 kij 的方法见下式。 kij ( t, t + n) = Q
L k , 第 k 只蚂蚁经过路径(i, j ) 0, 否则 ( 4) 式中, Q 为信息素强度, 在一定程度上影响算法的收敛速度; L k 为第k 只蚂蚁在本次循环中所走的路径长度。蚁周模型中, ( t, t+ n) 表示蚂蚁经过 n 步完成一次循环。上述方法称为蚁 周算法 ( ant - cycle algo rit hm ) 。该模型的时间复杂度为 O ( NC n2 m) , 其中 NC 表示循环的次数, n 为城市数。Ant - cy cle 算法框图如图 3 所示[5] 。
代码实现
import random
import math
#import matplotlib.pyplot as plt
#计算城市间距离的倒数
def distance1(city1,city2,coordinate):
dis=math.sqrt((coordinate[city1-1][0]-coordinate[city2-1][0])**2+\
(coordinate[city1-1][1]-coordinate[city2-1][1])**2)
if dis!=0:
dis=1/dis
return dis
def distance(data,coordinate):
dis=0
for i in range(1,len(data)):
dis+=math.sqrt((coordinate[data[i]-1][0]-coordinate[data[i-1]-1][0])**2+\
(coordinate[data[i]-1][1]-coordinate[data[i-1]-1][1])**2)
return dis
def P(T,i,F,alpha,beta,coordinate,m):
p=[]
sump=0
for j in range(len(F)):
p.append(((T[i-1][F[j]-1])**alpha)*(distance1(i,F[j],coordinate)**beta))
sump=sum(p)
for j in range(len(p)):
p[j]/=sump
return p
if __name__ == "__main__":
#初始化参数
m=31
alpha=1
beta=5
time=1000
rho=0.1
Q=100
T=[[1 for i in range(m)] for j in range(m)]
city=[i for i in range(1,32)]
#城市坐标
coordinate=[[40, 32], [93, 55], [38, 39], [11, 43], [32, 68], [54, 75], [19, 15], [56, 30], \
[16, 21], [77, 51], [48, 81], [68, 1], [99, 35], [73, 24], [62, 77], [90, 43], \
[87, 90], [96, 40], [72, 61], [78, 9], [96, 82], [61, 64], [61, 46], [86, 90], \
[20, 78], [5, 59], [88, 71], [96, 2], [95, 57], [12, 28],[55,20]]
n=0
bestdis=[]
while n<time:
mayi=[]
best=[]
F=[[i for i in range(1,m+1)] for j in range(m)]
for i in range(m):
a=random.randint(1,m)
mayi.append([a])
F[i].remove(a)
for i in range(m):
for j in range(m):
pnow=random.random()
p=P(T,mayi[i][j],F[i],alpha,beta,coordinate,m)
for k in range(len(p)):
if pnow <= sum(p[:(k+1)]):
mayi[i].append(F[i][k])
F[i].remove(F[i][k])
break
for i in range(m):
best.append(distance(mayi[i],coordinate))
dismax=max(best)
bestdis=mayi[best.index(dismax)]
n+=1
t=0
for i in range(m):
for j in range(m):
for k in range(m):
if distance1(mayi[k][i],mayi[k][j],coordinate)!= 0:
t+=Q/distance1(mayi[k][i],mayi[k][j],coordinate)
T[i][j]=(1-rho)*T[i][j]+t
print("最短距离为:",dismax)
print("路径为:",bestdis)