设计思路:
文件清单
文件 | 定位 | 作用 |
data.tsp | 数据 | 存储城市信息 |
main.py | 主模块 | 最近临点策略求解TSP问题 |
data.tsp:每行代表一个城市信息,第一列为城市标号,第二列为城市x坐标,第三列为城市y坐标。
0 26 23
1 95 14
2 10 20
3 89 70
4 84 10
main.py:主模块
# -*- coding:utf-8 -*-
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
# 读入数据
def read_data():
# 读入数据
data_frame = pd.read_csv("data.tsp", sep=" ", header=None)
# 截取城市坐标
return data_frame.iloc[:, 1:3]
# 距离矩阵
def distance_mat(cs):
_num = cs.shape[0]
_mat = np.zeros((_num, _num))
for _i in range(_num):
for _j in range(_num):
# 欧式距离
_mat[_i, _j] = np.sqrt(np.sum((cities[_i, :] - cities[_j, :]) ** 2))
return _mat
# 读入数据
data = read_data()
# 城市
cities = np.array(data)
# 城市数目
cities_num = cities.shape[0]
# 计算距离矩阵
mat = distance_mat(cities)
# 已经遍历过的城市
visited_cities = [0]
#
while True:
# 当前最小距离
min_distance = float('inf')
# 求最小距离
next_city = 0
k = 1
while True:
# 访问标记
visited = False
# 已经访问
if k in visited_cities:
visited = True
# 未访问且距离更小
if not visited and mat[k][visited_cities[-1]] < min_distance:
# 更新最小距离
next_city = k
min_distance = mat[k][visited_cities[-1]]
k += 1
if k >= cities_num:
break
# 添加下一位置
visited_cities.append(next_city)
# 判断终止
if len(visited_cities) >= cities_num:
break
# 城市
print('城市列表为:')
for city in cities:
print(city, end=',')
print()
# 距离矩阵
print('距离矩阵为:')
for i in mat:
for j in i:
print('%4d' % j, end='')
print()
print("路径为:")
for m in range(cities_num):
print("%s-> " % (visited_cities[m]), end='')
print('0')
# 画图
i = 0
for v in cities:
plt.scatter(v[0], v[1])
plt.annotate('city%d(%d, %d)' % (i, v[0], v[1]), [v[0] + 1, v[1] + 2])
i += 1
# 画线
for m in range(cities_num - 1):
c1 = visited_cities[m]
c2 = visited_cities[m + 1]
p1 = cities[c1]
p2 = cities[c2]
plt.plot([p1[0], p2[0]], [p1[1], p2[1]])
p1 = cities[visited_cities[0]]
p2 = cities[visited_cities[-1]]
plt.plot([p1[0], p2[0]], [p1[1], p2[1]])
plt.axis('off')
plt.show()
输出结果:
绘图结果: