第3关:蚁群算法 - 商队旅行最短路径计算参考

#encoding=utf8
import numpy as np
import random
#计算距离矩阵
def getdistmat(city):
    num = city.shape[0] 
    distmat = np.zeros((num,num))
    for i in range(num):
        for j in range(i,num):
            distmat[i][j] = distmat[j][i] = np.linalg.norm(city[i]-city[j])
    return distmat
def aco(city):
    '''
    city(ndarray):城市位置坐标
    '''
    numant = 15  #蚂蚁个数,通常为城市数目1.5倍
    numcity = city.shape[0] #城市个数
    alpha = 1   #信息素重要程度因子
    beta = 4    #启发函数重要程度因子
    rho = 0.05   #信息素的挥发速度
    Q = 1   #信息素常数
    n_iters = 50  #迭代次数
    distmat = getdistmat(city)   #城市的距离矩阵
    etatable = 1.0/(distmat+np.diag([1e10]*numcity)) #启发函数矩阵,表示蚂蚁从城市i转移到矩阵j的期望程度
    pheromonetable  = np.ones((numcity, numcity)) # 信息素矩阵
    pathtable = np.zeros((numant, numcity)).astype(int) #路径记录表

    # lengthaver = np.zeros(n_iters) #各代路径的平均长度
    # lengthbest = np.zeros(n_iters) #各代及其之前遇到的最佳路径长度
    # pathbest = np.zeros((n_iters, numcity),dtype=int) # 各代及其之前遇到的最佳路径长度
    #********* Begin *********#
    min_dist = float('inf')  # 最小距离  
    best_path = None  # 最佳路径  
    for iter in range(n_iters):  
        # 路径记录表  
        pathtable = np.zeros((numant, numcity)).astype(int)  
        lengthall = np.zeros(numant)  # 各蚂蚁的路径长度  
          
        # 随机初始化每只蚂蚁的起点  
        for i in range(numant):  
            pathtable[i, 0] = random.randint(0, numcity-1)  
          
        # 蚂蚁按照概率转移规则选择下一个城市  
        for i in range(numant):  
            visited = set()  
            visited.add(pathtable[i, 0])  
            for j in range(1, numcity):  
                probs = np.zeros(numcity)  
                for k in range(numcity):  
                    if k not in visited:  
                        probs[k] = np.power(pheromonetable[pathtable[i, j-1], k],alpha) * np.power(etatable[pathtable[i, j-1], k], beta)  
                probs /= probs.sum()  
                cumprobs = probs.cumsum()  
                r = random.random()  
                for k in range(numcity):  
                    if cumprobs[k] >= r:  
                        pathtable[i, j] = k  
                        break  
                visited.add(k)  
            # 计算路径长度  
            lengthall[i] = np.sum(distmat[pathtable[i, :-1], pathtable[i, 1:]])  
            lengthall[i] += distmat[pathtable[i, -1], pathtable[i, 0]]  # 返回起点  
          
        # 更新信息素  
        if min(lengthall) < min_dist:  
            min_dist = min(lengthall)  
            best_path = pathtable[np.argmin(lengthall), :]  
          
        # 信息素挥发和更新  
        pheromonetable *= (1 - rho)  
        for i in range(numant):  
            for j in range(numcity-1):  
                pheromonetable[pathtable[i, j], pathtable[i, j+1]] += Q / lengthall[i]  
            pheromonetable[pathtable[i, -1], pathtable[i, 0]] += Q / lengthall[i]  
    #********* End *********#
    return min_dist
city = np.array([[0.01360298, 0.4581784 ],
            [0.66441875, 0.46481977],
            [0.55980498, 0.19154023],
            [0.12535054, 0.16271053],
            [0.47544932, 0.35714676],
            [0.81562109, 0.63469573],
            [0.77387573, 0.52801719],
            [0.95461222, 0.47996912],
            [0.14426016, 0.32351287],
            [0.94679974, 0.23545779]])
if abs(aco(city)-2.558)<0.3:
    print(1)
else:
    print(0)

弄了没啥毛病的有空就会发,有些有bug就不发,仅当参考。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值