- 读取城市坐标数据,建立城市名称列表和城市坐标数组
- 建立城市距离矩阵,计算任意两城市之间的欧氏距离
- 计算路径的总距离,从起点出发,依次计算到下一城市的距离,直到回到起点
- 选择下一城市,按信息素浓度和启发函数计算各个未访问城市的转移概率,并根据概率选择下一城市
- 更新信息素,在所有路径中找到最短路径,并更新最短路径上的信息素,同时挥发其它路径上的信息素
- 主循环,迭代多次,在每次迭代中遍历所有蚂蚁建立路径,更新信息素,并记录最短路径和距离
- 打印并绘制最短路径的结果
import numpy as np
import matplotlib.pyplot as plt
import math
import random
ant_num = 50
iter_num = 100
rho = 0.1
alpha = 1
beta = 2
def read_data():
city_name = []
city_position = []
with open("demo.txt", 'r',encoding='utf-8') as f:
lines = f.readlines()
for line in lines:
line = line.split('\n')[0]
line = line.split('\t')
city_name.append(line[0])
city_position.append([float(line[1]), float(line[2])])
city_position = np.array(city_position)
return city_name, city_position
def distance_Matrix(city_name, city_position):
global city_count, distance_city
city_count = len(city_name)
distance_city = np.zeros((city_count, city_count))
for i in range(city_count):
for j in range(city_count):
distance_city[i][j] = math.sqrt((city_position[i][0] - city_position[j][0]) ** 2 + (city_position[i][1] - city_position[j][1]) ** 2)
return city_count, distance_city
def get_distance(path):
distance = 0
distance += distance_city[0][path[0]]
for i in range(len(path)):
if i == len(path) - 1:
distance += distance_city[0][path[i]]
else:
distance += distance_city[path[i]][path[i + 1]]
return distance
def choose_next_city(path, distance_city, pheromone):
next_cities = list(set(range(city_count)) - set(path))
probs = [0] * len(next_cities)
for i in range(len(next_cities)):
pheromone_value = pheromone[path[-1]][next_cities[i]]
inverse_distance = 1 / distance_city[path[-1]][next_cities[i]]
prob = pheromone_value ** alpha * inverse_distance ** beta
probs[i] = prob
next_city = np.random.choice(next_cities, p = probs/sum(probs))
return next_city
def update_pheromone(paths, pheromone, rho, distance_city):
distance_best_path = np.min([get_distance(path) for path in paths])
for path in paths:
if get_distance(path) == distance_best_path:
for i in range(city_count - 1):
pheromone[path[i]][path[i+1]] = (1 - rho) * pheromone[path[i]][path[i+1]] + 1 / distance_city[path[i]][path[i+1]]
city_name, city_position = read_data()
city_count, distance_city = distance_Matrix(city_name, city_position)
pheromone = np.ones((city_count, city_count))
paths = []
for iter in range(iter_num):
for i in range(ant_num):
path = [0]
visited = [path[0]]
while len(visited) != city_count:
next_city = choose_next_city(path, distance_city, pheromone)
path.append(next_city)
visited.append(next_city)
path.append(0)
paths.append(path)
update_pheromone(paths, pheromone, rho, distance_city)
best_path = min(paths, key=lambda x: get_distance(x))
X = []
Y = []
for i in best_path:
X.append(city_position[i, 0])
Y.append(city_position[i, 1])
plt.figure()
plt.subplot(2, 1, 1, facecolor = 'w')
plt.plot(X, Y, '-o')
plt.xlabel('经度')
plt.ylabel('纬度')
plt.title("ACO_TSP")
for i in range(len(X)):
plt.annotate(city_name[best_path[i]], xy=(X[i], Y[i]), xytext=(X[i] + 0.1, Y[i] + 0.1))
plt.subplot(2, 1, 2, facecolor = 'w')
plt.xlabel('经度')
plt.ylabel('纬度')
plt.title("ACO_TSP")
plt.subplots_adjust(hspace=0.6)
plt.plot(X, Y)
[<matplotlib.lines.Line2D at 0x15a632c82e0>]