import random
import argparse
import numpy as np
import matplotlib.pyplot as plt
from math import radians, cos, sin, asin, sqrt
def earth_distance(lon1, lat1, lon2, lat2):
"""计算地球表面两点间距离(公里)"""
lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2
return 6371 * 2 * asin(sqrt(a))
def city_distance(cities):
"""生成城市距离矩阵"""
N = len(cities)
matrix = np.zeros((N, N))
for i in range(N):
for j in range(i, N):
dist = earth_distance(*cities[i], *cities[j])
matrix[i][j] = matrix[j][i] = round(dist, 2)
return matrix
def calc_path_distance(matrix, path):
"""计算路径总距离"""
return sum(matrix[path[i]][path[i + 1]] for i in range(len(path) - 1))
def read_from_coords_txt(lines):
"""从文本行解析坐标数据"""
return [list(map(float, line.strip().split())) for line in lines]
def read_data_files(use_test=False):
"""加载数据集"""
all_coords = []
for i in range(3): # 默认3个数据集
filename = f'data/test_{i}.txt' if use_test else f'data/val_{i}.txt'
with open(filename, 'r') as f:
all_coords.append(read_from_coords_txt(f.readlines()))
return all_coords
def plotTSP(path, points):
"""可视化TSP路径"""
x = [points[i] for i in path]
y = [points[i][1] for i in path]
plt.figure(figsize=(10, 6))
plt.plot(x, y, 'co') # 绘制城市点
# 绘制路径箭头
a_scale = max(x) / 100
for i in range(len(path) - 1):
dx = x[i + 1] - x[i]
dy = y[i + 1] - y[i]
plt.arrow(x[i], y[i], dx, dy, head_width=a_scale,
color='g', length_includes_head=True)
plt.title(f"TSP Solution (Path length: {calc_path_distance(city_distance(points), path):.2f} km)")
plt.show()
def ant_colony_tsp(coords, iterations=100, ants=20, alpha=1, beta=5, rho=0.5):
"""蚁群优化算法实现"""
num_nodes = len(coords)
dist_matrix = city_distance(coords)
pheromone = np.ones((num_nodes, num_nodes))
best_path = None
best_length = float('inf')
for _ in range(iterations):
paths = []
lengths = []
for _ in range(ants):
path =
visited = set()
while len(path) < num_nodes:
current = path[-1]
probs = []
for node in range(num_nodes):
if node not in visited:
phe = pheromone[current][node] ** alpha
heuristic = (1 / dist_matrix[current][node]) ** beta
probs.append((node, phe * heuristic))
total = sum(p[1] for p in probs)
probs = [(p, p[1] / total) for p in probs]
chosen = random.choices(probs, weights=[p[1] for p in probs])
path.append(chosen)
visited.add(chosen)
path.append(0) # 返回起点
length = calc_path_distance(dist_matrix, path)
paths.append(path)
lengths.append(length)
if length < best_length:
best_path, best_length = path, length
# 更新信息素
pheromone *= (1 - rho)
for path, length in zip(paths, lengths):
for i in range(len(path) - 1):
pheromone[path[i]][path[i + 1]] += 1 / length
return best_path
def main():
parser = argparse.ArgumentParser(description='TSP Solver')
parser.add_argument('--test', action='store_true', help='Run in test mode')
parser.add_argument('--visualize', action='store_true', help='Show solution visualization')
args = parser.parse_args()
if args.test:
# 测试模式
all_coords = read_data_files(use_test=True)
with open('result.txt', 'r') as f:
paths = [list(map(int, line.strip().split())) for line in f]
for i, (coords, path) in enumerate(zip(all_coords, paths)):
assert path == path[-1] == 0, "Invalid path"
assert len(path) == len(coords) + 1, "Path length mismatch"
distance = calc_path_distance(city_distance(coords), path)
print(f'Dataset {i} path length: {distance:.2f} km')
if args.visualize:
plotTSP(path, coords)
else:
# 求解模式
all_coords = read_data_files()
results = []
for i, coords in enumerate(all_coords):
path = ant_colony_tsp(coords)
results.append(" ".join(map(str, path)))
print(f'Dataset {i} solution: {path}')
if args.visualize:
plotTSP(path, coords)
with open('result.txt', 'w') as f:
f.write("\n".join(results))
if __name__ == "__main__":
main() 如何用 Python 实现基于蚁群优化算法的旅行商问题,考虑物流节点转运时间和路程时间限制并在三天内完成配送
最新发布