蚁群算法 python_Python蚁群算法实现

时间:2018-12-12

概述:蚁群算法

Python蚁群算法实现,使用工具:Pycharm ,Python版本为3.6.3,作者:李劭明。使用蚁群算法得到各个城市间的距离,下面来看详细的代码:

import numpy as np #数据处理包

import matplotlib.pyplot as plt#绘图包

#40座城市坐标

coordinates = np.array([[880.0,660.0],[25.0,230.0],[525.0,1000.0],[580.0,1175.0],[650.0,1130.0],

[1605.0,620.0],[1220.0,580.0],[1465.0,200.0],[1530.0,5.0],[845.0,680.0],

[725.0,370.0],[145.0,665.0],[415.0,635.0],[510.0,875.0],[560.0,365.0],

[300.0,465.0],[520.0,585.0],[480.0,415.0],[835.0,625.0],[975.0,580.0],

[420.0,555.0],[575.0,665.0],[1150.0,1160.0],[700.0,580.0],[685.0,595.0],

[685.0,610.0],[770.0,610.0],[795.0,645.0],[720.0,635.0],[760.0,650.0],

[475.0,960.0],[95.0,260.0],[875.0,920.0],[700.0,500.0],[555.0,815.0],

[830.0,485.0],[1170.0, 65.0],[830.0,610.0],[605.0,625.0],[595.0,360.0],

])

"""

得到各个城市间的距离

由于距离是两点之间的,因此,会返回一个对称矩阵

"""

def getdistmat(coordinates):

num = coordinates.shape[0] # 城市数量40

distmat = np.zeros((num,num))# 初始化距离都为0

for i in range(num): # i从0到39

for j in range(i, num): # j从i到39

distmat[i][j] = distmat[j][i] = np.linalg.norm(coordinates[i] - coordinates[j])# 得到对称矩阵,矩阵为城市间距离

return distmat

# 把得到最优路径轨迹绘制出来

def draw_graphics(save_path,new_coordinates):

global coordinates # 引用全局变量

x=[] #用来保存new_coordinates中每个元素的x值

y=[] #用来保存new_coordinates中每个元素的y值

for i in range(len(new_coordinates)):

x.append(new_coordinates[i][0]) #得到x坐标值集合

y.append(new_coordinates[i][1]) #得到y坐标值集合

x.append(new_coordinates[0][0]) #把第一个城市的x值放到x集合最后面

y.append(new_coordinates[0][1]) #把第一个城市的y值放到y集合最后面

fig=plt.figure()

plt.scatter(x,y,c='b',s=5)

plt.plot(x,y)

for i in save_path:

plt.text(coordinates[int(i)][0],coordinates[int(i)][1],r'%s'%int(i),fontdict={'size':7,'color':'r'})

plt.show()

# 变量初始化

numant = 30 # 蚂蚁个数

numcity = coordinates.shape[0] # 城市个数40

alpha = 1 # 信息素权重参数

beta=1 # 距离权重参数

rho = 0.1 # 信息素的挥发速度

Q =1 # 信息素强度,假设为1

iter = 0

itermax =300# 循环300次

distmat = getdistmat(coordinates)# 城市间的距离矩阵

etatable = 1.0 / (distmat + np.diag([1e10] * numcity)) # 启发函数矩阵,表示蚂蚁从城市i转移到j的期望程度

# 此处添加1e10在对角上,表示自己到自己的距离为无穷小,相当于0

pheromonetable = np.ones((numcity, numcity)) # 信息素表全部初始化为1

pathtable = np.zeros((numant, numcity)).astype(int) # 初始化路径记录表全部为0

lengthaver = np.zeros(itermax) # 各代路径的平均长度

lengthbest = np.zeros(itermax) # 各代及其之前遇到的最佳路径长度

pathbest = np.zeros((itermax, numcity)) # 各代及其之前遇到的最佳路径长度所对应城市走过的路迹

# 大循环

while iter < itermax:

# 随机产生各个蚂蚁的起点城市

if numant <= numcity: # 城市数比蚂蚁数多

pathtable[:, 0] = np.random.permutation(range(0, numcity))[:numant]# 蚂蚁随机分配到各个城市

else: # 蚂蚁数比城市数多,需要补足

pathtable[:numcity, 0] = np.random.permutation(range(0, numcity))[:]

pathtable[numcity:, 0] = np.random.permutation(range(0, numcity))[:numant - numcity]

length = np.zeros(numant) # 每只蚂蚁走过路径距离矩阵

for i in range(numant):# 所有的蚂蚁都要走遍每个城市

visiting = pathtable[i, 0] # 当前所在的城市

unvisited = set(range(numcity)) # 未访问的城市

unvisited.remove(visiting) # 删除访问过的元素

for j in range(1, numcity): # 循环numcity-1次,访问剩余的numcity-1个城市

# 每次用轮盘法选择下一个要访问的城市

listunvisited = list(unvisited)

probtrans = np.zeros(len(listunvisited))

for k in range(len(listunvisited)):

probtrans[k] = np.power(pheromonetable[visiting][listunvisited[k]], alpha) * np.power(

etatable[visiting][listunvisited[k]], beta) # probtrans由信息素浓度和距离共同决定

cumsumprobtrans = (probtrans / sum(probtrans)).cumsum()

cumsumprobtrans -= np.random.rand()

next_index = 0# 选出第一个cumsumprobtrans>0所对应的城市索引

for value in cumsumprobtrans:

if value > 0:

break

else:

next_index += 1

k = listunvisited[next_index] # 下一个要访问的城市

pathtable[i, j] = k # 更新禁忌表

unvisited.remove(k) # 把已经访问过的城市从unvisited中删除

length[i] += distmat[visiting][k] # 走过城市距离求和

visiting = k # 城市k已经被访问过了

length[i] += distmat[visiting][pathtable[i, 0]] # 蚂蚁的最终路径距离还要加上最后一个城市和第一个城市的距离

# 包含所有蚂蚁的一个迭代结束后,统计本次迭代的若干统计参数

lengthaver[iter] = length.mean() # 本次循环30只蚂蚁走完所有城市回到原点距离和平均值

if iter == 0: # 第一次循环

lengthbest[iter] = length.min()# 走过所有城市路径和最小值

pathbest[iter] = pathtable[length.argmin()].copy()# 最小值所对应城市走过的路迹

else:

if length.min() > lengthbest[iter - 1]: # 如果最小值比前面的还小,保持前面的值

lengthbest[iter] = lengthbest[iter - 1]

else: # 把最小值重新赋值

lengthbest[iter] = length.min()

pathbest[iter] = pathtable[length.argmin()].copy()

# 更新信息素

changepheromonetable = np.zeros((numcity, numcity))

for i in range(numant):

for j in range(numcity - 1):

changepheromonetable[pathtable[i, j]][pathtable[i, j + 1]] += Q / distmat[pathtable[i, j]][

pathtable[i, j + 1]] # 信息素的增加多少与城市间的距离成反比

changepheromonetable[pathtable[i, j + 1]][pathtable[i, 0]] += Q / distmat[pathtable[i, j + 1]][pathtable[i, 0]]# 重新回到起始点蚂蚁更新信息素

pheromonetable = (1 - rho) * pheromonetable + changepheromonetable # rho为信息素挥发因子

iter += 1 # 迭代次数指示器+1

print(lengthbest)

save_path=[] #保存最终的最佳路径轨迹

new_coordinates=[]

for i in pathbest: # 获得最优路径

if i[0]!=i[1]:

save_path=i.copy()

print(save_path) # 得到最优路径城市遍历轨迹

for i in range(coordinates.shape[0]): # 得到最优路径城市遍历相对应的坐标

new_coordinates.append(coordinates[int(save_path[i])])

draw_graphics(save_path,new_coordinates)# 绘制图形函数

再次提示,在Pycharm ,Python版本为3.6.3的环境下编译成功。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值