人工智能蚁群算法简易版

头歌人工智能平台下的蚁群算法,以下是本人对算法的补充 

import numpy as np
import math
import random
import time

# 31个城市的坐标
city_condition=[[106.54,29.59],[ 91.11,29.97],[ 87.68,43.77],[106.27,38.47],[111.65,40.82],
 [108.33,22.84],[126.63,45.75],[125.35,43.88],[123.38,41.8 ],[114.48,38.03],[112.53,37.87],
 [101.74,36.56],[117.0,36.65],[113.6,34.76],[118.78,32.04],[117.27,31.86],
 [120.19,30.26],[119.3,26.08],[115.89,28.68],[113.0,28.21],[114.31,30.52],
 [113.23,23.16],[121.5,25.05],[110.35,20.02],[103.73,36.03],[108.95,34.27],
 [104.06,30.67],[106.71,26.57],[102.73,25.04],[114.1,22.2 ],[113.33,22.13]]

"""
距离矩阵和总距离的计算
"""
#距离矩阵
city_count = 31
Distance = np.zeros((city_count, city_count))
for i in range(city_count):
    for j in range(city_count):
        if i != j:
            Distance[i][j] = math.sqrt((city_condition[i][0] - city_condition[j][0]) ** 2 + (city_condition[i][1] - city_condition[j][1]) ** 2)
        else:
            Distance[i][j] = 100000

#适应度计算
def get_total_distance(path_new):
    distance = 0
    # ********** Begin **********#
    for i in range(city_count):
        if i == city_count - 1:  # 最后一个城市回到起点
            distance += Distance[path_new[i]][path_new[0]]
        else:
            distance += Distance[path_new[i]][path_new[i + 1]]
    return distance
    # ********** End **********#
    return distance
"""
两个难点
1.城市的选择:初始城市选择和下一个城市的选择设计
2.信息素的更新
"""
def main():
    ##参数设计
    # 蚂蚁数量
    AntCount = 10
    # 城市数量
    city_count = 31
    # 信息素
    alpha = 1  # 信息素重要程度因子
    beta = 5  # 启发函数重要程度因子
    rho = 0.1 #挥发速度
    iter = 0  # 迭代初始值
    iteration = 200  # 最大迭代值
    Q = 1
    # 初始信息素矩阵,全是为1组成的矩阵
    pheromonetable = np.ones((city_count, city_count))
    # print(pheromonetable)
    # 候选集列表
    candidate = np.zeros((AntCount, city_count)).astype(int)  # 存放100只蚂蚁的路径(一只蚂蚁一个路径),一共就Antcount个路径,一共是蚂蚁数量*31个城市数量
    path_best = np.zeros((iteration, city_count))  # path_best存放的是相应的,每次迭代后的最优路径,每次迭代只有一个值
    # 存放每次迭代的最优距离
    distance_best = np.zeros(iteration)
    #怎么处理对角线的元素是0的情况
    etable = 1.0 / Distance  # 倒数矩阵

    while iter < iteration:
        """
        #路径创建
        """
        ## first:蚂蚁初始点选择
        # ********** Begin **********#
        start_cities = random.choices(range(city_count), k=AntCount)  # 随机选择蚂蚁的起始城市
        candidate[:, 0] = start_cities  # 将每个蚂蚁的起始城市记录在候选集列表中
        # ********** End **********#

        ## second:选择下一个城市选择
        length = np.zeros(AntCount)
        for i in range(AntCount):
            # 移除已经访问的第一个元素
            unvisit = list(range(city_count))  # 列表形式存储没有访问的城市编号
            visit = candidate[i, 0]  # 当前所在点,第i个蚂蚁在第一个城市
            unvisit.remove(visit)  # 在未访问的城市中移除当前开始的点
            for j in range(1, city_count):#访问剩下的city_count个城市,city_count次访问
                protrans = np.zeros(len(unvisit))#每次循环都更改当前没有访问的城市的转移概率矩阵1*30,1*29,1*28...
                # 下一城市的概率函数
                for k in range(len(unvisit)):
                    # 计算当前城市到剩余城市的(信息素浓度^alpha)*(城市适应度的倒数)^beta
                    # etable[visit][unvisit[k]],(alpha+1)是倒数分之一,pheromonetable[visit][unvisit[k]]是从本城市到k城市的信息素
                    # ********** Begin**********#
                    protrans[k] = (pheromonetable[visit][unvisit[k]] ** alpha) * (etable[visit][unvisit[k]] ** beta)
                    # ********** End **********#
                # 累计概率,轮盘赌选择
                cumsumprobtrans = (protrans / sum(protrans)).cumsum()
                cumsumprobtrans -= np.random.rand()
                # 求出离随机数产生最近的索引值
                k = unvisit[list(cumsumprobtrans > 0).index(True)]
                # 下一个访问城市的索引值
                candidate[i, j] = k
                unvisit.remove(k)
                length[i] += Distance[visit][k]
                visit = k  # 更改出发点,继续选择下一个到达点
            length[i] += Distance[visit][candidate[i, 0]]#最后一个城市和第一个城市的距离值也要加进去
        """
        更新路径等参数
        """
        # 如果迭代次数为一次,那么无条件让初始值代替path_best,distance_best.
        if iter == 0:
            distance_best[iter] = length.min()
            path_best[iter] = candidate[length.argmin()].copy()
        else:
            # 如果当前的解没有之前的解好,那么当前最优还是为之前的那个值;并且用前一个路径替换为当前的最优路径
            if length.min() > distance_best[iter - 1]:
                distance_best[iter] = distance_best[iter - 1]
                path_best[iter] = path_best[iter - 1].copy()
            else:  # 当前解比之前的要好,替换当前解和路径
                distance_best[iter] = length.min()
                path_best[iter] = candidate[length.argmin()].copy()

        """
            信息素的更新
        """
        #信息素的增加量矩阵

        changepheromonetable = np.zeros((city_count, city_count))
        for i in range(AntCount):
            for j in range(city_count - 1):
                # 当前路径比如城市23之间的信息素的增量:1/当前蚂蚁行走的总距离的信息素
                # ********** Begin **********#
                changepheromonetable[candidate[i, j]][candidate[i, j + 1]] += Q / length[i]
                # ********** End **********#
            #最后一个城市和第一个城市的信息素增加量
            changepheromonetable[candidate[i, j + 1]][candidate[i, 0]] += Q / length[i]
        #信息素更新的公式:

        # ********** Begin **********#
        pheromonetable *= (1 - rho)  # 先挥发
        for i in range(AntCount):
            for j in range(city_count - 1):
                pheromonetable[candidate[i, j]][candidate[i, j + 1]] += changepheromonetable[candidate[i, j]][candidate[i, j + 1]]
            pheromonetable[candidate[i, city_count - 1]][candidate[i, 0]] += changepheromonetable[candidate[i, city_count - 1]][candidate[i, 0]]
        # ********** End **********#
        iter += 1
    return distance_best,path_best,iteration


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值