人工智能实验:蚁群算法求解TSP问题(Python代码实现,附有详细实验报告地址)

项目简介

这是人工智能实验课的一次作业,项目文件中包含两个py文件,其中Main.py是算法的主体,而其他一些实现则放在AidFunctions.py文件中。代码注释比较详细,可以对照实验报告进行阅览。

项目代码

Main.py

#### 函数库导入区域 ####
import numpy as np
import AidFunctions
import matplotlib.pyplot as plt
import time

#### 参数定义区域 ####
CityCount=20               # 定义城市个数(也就是问题规模)
AntCount=30                # 定义蚂蚁数量
MaxIteration=200           # 定义最大迭代次数
Alpha=3                    # 定义信息素因子
Beta=4                     # 定义启发函数因子
Q=100                      # 定义算法信息素常数
VolatilizationRate=0.5     # 定义算法中的挥发率

#### 其他变量定义区域 ####
np.random.seed(2)                          # 固定随机数种子,方便多次进行验证
RouteRecordMin=np.zeros((1,MaxIteration))  # 用于记录每一次迭代中的局部最优解
RouteRecordMax=np.zeros((1,MaxIteration))  # 用于记录每一次迭代中的最长回路长度
RouteRecordAve=np.zeros((1,MaxIteration))  # 用于记录每一次迭代中的蚂蚁周游的平均路径长度
BestRoute=[]                               # 用于记录最优环游路线中城市的经过顺序

#### 主函数部分 ####

### 初始化部分 ###
# 首先通过随机数生成指定个数城市的横纵坐标(此时不考虑三维情况)
X = np.random.uniform(1, 100, (1, CityCount))
Y = np.random.uniform(1, 100, (1, CityCount))
# 根据城市个数生成城市距离矩阵
DistanceMatrix=AidFunctions.GetDistanceMatrix(X,Y,CityCount)

## 开始计时 ##
start=time.time()

# 根据蚂蚁的数量为每一只蚂蚁随机分配初始城市
AntPlaceVector=np.random.randint(0,CityCount-1,(1,AntCount))

# 接着生成初始信息素矩阵
# 首先随机生成一条周游路线以初始化每条边上的信息素
RandomRoute=np.random.permutation(np.arange(CityCount))
TempLength=0
for i in range(CityCount-1):
    TempLength+=DistanceMatrix[RandomRoute[i],RandomRoute[i+1]]
TempLength+=DistanceMatrix[RandomRoute[0],RandomRoute[CityCount-1]]
PheromoneMatrix=np.full((CityCount,CityCount),1/TempLength)
# 对角线上的元素初始化为零
for i in range(CityCount):
    PheromoneMatrix[i,i]=0

### 循环迭代部分 ###
for iteration in range(MaxIteration):
    # 创建一个禁忌表,用双重列表的形式进行定义
    TabooList = []
    # 首先定义禁忌表中的每一个元素都是一个列表,表示某一只蚂蚁的禁忌表
    for i in range(AntCount):
        TabooList.append([])
    # 接下来对禁忌表中进行第一轮内容填充
    for i in range(AntCount):
        TabooList[i].append(AntPlaceVector[0, i])
    ## 首先求出每一轮迭代中每一只蚂蚁进行下一目的地选择的概率向量
    for i in range(CityCount-1):
        for ant in range(AntCount):
            ProbilityVector = np.zeros((1, CityCount))
            for city in range(CityCount):
                if city in TabooList[ant]:
                    continue
                TempPheromone = PheromoneMatrix[TabooList[ant][len(TabooList[ant]) - 1], city]
                TempNegDistance = 1 / DistanceMatrix[TabooList[ant][len(TabooList[ant]) - 1], city]
                ProbilityVector[0, city] = (TempPheromone ** Alpha) * (TempNegDistance ** Beta)
            Pro_Sum = np.sum(ProbilityVector, axis=1)
            ProbilityVector = ProbilityVector / Pro_Sum
            ## 求出概率向量后使用逐次轮盘法进行抽签得到每只蚂蚁下一次所到达的城市
            Next_City = np.random.choice(np.arange(0, CityCount), (1, 1), p=ProbilityVector[0, :])[0, 0]
            TabooList[ant].append(Next_City)
    ## 至此已经得到了某一轮迭代中每一只蚂蚁的行进路线,用一个列表表示,接下来分别计算每只蚂蚁的周游路线的长度
    RouteLengths=[]
    for ant in range(AntCount):
        TempRouteLength=0
        for i in range(CityCount-1):
            Route=DistanceMatrix[TabooList[ant][i],TabooList[ant][i+1]]
            TempRouteLength+=Route
        TempRouteLength+=DistanceMatrix[TabooList[ant][0],TabooList[ant][len(TabooList[ant])-1]]
        RouteLengths.append(TempRouteLength)
    ## 记录此时的局部最优解
    BestRoute=TabooList[RouteLengths.index(min(RouteLengths))]
    RouteRecordMin[0,iteration]=min(RouteLengths)
    RouteRecordMax[0, iteration] = max(RouteLengths)
    RouteRecordAve[0,iteration]=sum(RouteLengths)/len(RouteLengths)
    BestRoute=TabooList[RouteLengths.index(min(RouteLengths))]

    ## 接下来更新信息素矩阵
    New_PheromoneMatrix=np.zeros((CityCount,CityCount))
    for row in range(CityCount):
        for col in range(row+1):
            if row == col:
                break
            NewInfo=0
            ## 如果某只蚂蚁经过了该条路径,则会增加该路径上的信息素
            for ant in range(AntCount):
                for i in range(CityCount-1):
                    if TabooList[ant][i] == row and TabooList[ant][i + 1] == col:
                        NewInfo += (Q / RouteLengths[ant])
                if TabooList[ant][CityCount - 1] == row and TabooList[ant][0] == col:
                    NewInfo += (Q / RouteLengths[ant])
                if TabooList[ant][CityCount - 1] == col and TabooList[ant][0] == row:
                    NewInfo += (Q / RouteLengths[ant])
            New_PheromoneMatrix[row,col]=(1-VolatilizationRate)*PheromoneMatrix[row,col]+VolatilizationRate*NewInfo
            New_PheromoneMatrix[col,row]=(1-VolatilizationRate)*PheromoneMatrix[row,col]+VolatilizationRate*NewInfo
    PheromoneMatrix=New_PheromoneMatrix

## 结束计时 ##
end=time.time()
Time_Gap=end-start

### 绘制最短距离随迭代次数的变化情况图
plt.figure(2)
line1,=plt.plot(range(MaxIteration),RouteRecordMin[0,:].tolist(),'r')
line2,=plt.plot(range(MaxIteration),RouteRecordAve[0,:].tolist(),'g')
line3,=plt.plot(range(MaxIteration),RouteRecordMax[0,:].tolist(),'b')
plt.xlabel("迭代次数",fontproperties="Simhei")
plt.ylabel("最短距离",fontproperties="Simhei")
plt.title("最短距离随迭代次数的变化情况图",fontproperties="Simhei")
plt.grid(True)
plt.legend([line3,line2,line1],["Max","Ave","Min"],loc="upper right")
plt.show()

## 最后作出迭代完成后最优环游路线的示意图
X=X[0,:].tolist()
Y=Y[0,:].tolist()
Best_X=[]
Best_Y=[]
for city in BestRoute:
    Best_X.append(X[city])
    Best_Y.append(Y[city])
Best_X.append(X[BestRoute[0]])
Best_Y.append(Y[BestRoute[0]])
plt.figure(3)
plt.plot(Best_X,Best_Y,'b-o')
plt.xlabel("横坐标",fontproperties="Simhei")
plt.ylabel("纵坐标",fontproperties="Simhei")
plt.title("最短环游路线示意图",fontproperties="Simhei")
plt.show()

## 输出算法的运行时间和相关的最短、最长和平均路径长度
print("算法的运行时间为",Time_Gap,"秒")
print("最短环游路径的长度为:",RouteRecordMin[0,MaxIteration-1])
print("最长环游路径的长度为:",RouteRecordMax[0,MaxIteration-1])
print("平均环游路径的长度为:",RouteRecordAve[0,MaxIteration-1])

AidFunctions.py

import matplotlib.pyplot as plt
import numpy as np

####求出距离矩阵的函数 ####
def GetDistanceMatrix(X,Y,CityCount):
    # 作出初始城市位置的散点图
    plt.figure(1)
    plt.plot(X,Y,'r''o')
    plt.xlabel("横坐标",fontproperties="Simhei")
    plt.ylabel("纵坐标",fontproperties="Simhei")
    plt.title("城市分布散点图",fontproperties="Simhei")
    plt.show()
    # 生成一个方阵作为任意两城市之间的距离矩阵
    DistanceMatrix=np.zeros((CityCount,CityCount))
    # 通过逐行逐列遍历的方式填充矩阵元素(第i行第j列的元素表示i和j两个城市之间的距离)
    for row in range(CityCount):
        for col in range(CityCount):
            DistanceMatrix[row,col]=((X[0,row]-X[0,col])**2+(Y[0,row]-Y[0,col])**2)**0.5
    # 将进行了填充后的距离矩阵返回输出
    return DistanceMatrix

实验报告

实验报告的部分内容如下所示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
获取实验报告和源代码点击这里

  • 9
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
蚁群算法是一种模拟蚂蚁觅食行为的优化算法,常用于求解TSP问题。以下是Python实现蚁群算法求解TSP问题的示例代码: ``` python import numpy as np import random # TSP距离矩阵 distance_matrix = [[0, 1, 2, 3, 4], [1, 0, 3, 2, 5], [2, 3, 0, 4, 6], [3, 2, 4, 0, 7], [4, 5, 6, 7, 0]] # 蚂蚁数量 ant_count = 10 # 蚂蚁移动距离的影响因子 alpha = 1 # 蚂蚁信息素浓度的影响因子 beta = 5 # 信息素的挥发系数 rho = 0.1 # 初始信息素浓度 tau0 = 1 # 迭代次数 iteration_count = 100 # 初始化信息素浓度矩阵 tau = np.zeros((5, 5)) + tau0 # 计算路径长度 def path_length(path): length = 0 for i in range(len(path) - 1): length += distance_matrix[path[i]][path[i + 1]] length += distance_matrix[path[-1]][path[0]] return length # 选择下一个节点 def select_next_node(current_node, visited_nodes): # 计算当前节点到其他节点的信息素浓度和启发式因子 probabilities = [] for i in range(len(distance_matrix)): if i not in visited_nodes: tau_ij = tau[current_node][i] eta_ij = 1 / distance_matrix[current_node][i] p = (tau_ij ** alpha) * (eta_ij ** beta) probabilities.append(p) else: probabilities.append(0) # 根据概率选择下一个节点 probabilities = probabilities / np.sum(probabilities) next_node = np.random.choice(range(len(distance_matrix)), p=probabilities) return next_node # 更新信息素浓度 def update_pheromone(ant_paths): global tau # 挥发信息素 tau = (1 - rho) * tau # 更新信息素 for path in ant_paths: length = path_length(path) for i in range(len(path) - 1): tau[path[i]][path[i + 1]] += 1 / length tau[path[-1]][path[0]] += 1 / length # 蚁群算法主函数 def ant_colony_optimization(): global tau shortest_path_length = float('inf') shortest_path = [] for i in range(iteration_count): # 初始化蚂蚁位置 ant_positions = [random.randint(0, len(distance_matrix) - 1) for _ in range(ant_count)] ant_paths = [] # 蚂蚁移动 for j in range(len(distance_matrix) - 1): for k in range(ant_count): current_node = ant_positions[k] visited_nodes = ant_positions[:k] + ant_positions[k + 1:j + 1] next_node = select_next_node(current_node, visited_nodes) ant_positions[k] = next_node ant_paths.append(ant_positions.copy()) # 更新信息素浓度 update_pheromone(ant_paths) # 记录最短路径 min_path_index = np.argmin([path_length(path) for path in ant_paths]) if path_length(ant_paths[min_path_index]) < shortest_path_length: shortest_path_length = path_length(ant_paths[min_path_index]) shortest_path = ant_paths[min_path_index] return shortest_path, shortest_path_length # 测试 shortest_path, shortest_path_length = ant_colony_optimization() print('Shortest path:', shortest_path) print('Shortest path length:', shortest_path_length) ``` 注:该示例代码中的TSP距离矩阵为一个简单的5个节点的例子,实际使用时需根据具体问题进行修改。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值