diff --git a/TSP/src/TSP.py b/TSP/src/TSP.py new file mode 100644 index 0000000..e8b491d --- /dev/null +++ b/TSP/src/TSP.py @@ -0,0 +1,143 @@ +import numpy as np +import matplotlib.pyplot as plt +import pdb +import random as rd +from math import sqrt, exp +from os import path +from matplotlib.lines import Line2D +import matplotlib.animation as animation +"旅行商问题 ( TSP , Traveling Salesman Problem )" +''' +编写模拟退火算法解旅行商问题 +实现TSP的模拟退火算法函数,输入是矩阵表示的图,输出是路径 +可视化显示中间变化过程 +要有详细的注释 +使用python语言 +''' + +# input + + +def loadin_data(): + local_path = path.dirname(__file__) + with open(local_path + '/../testdata/1.txt', 'r') as f: + data = f.read() + data = data.split() + length = len(data) + x = [] + y = [] + for i in range(length//2): + x.append(int(data[2*i])) + y.append(int(data[2*i+1])) + f.close() + # print(data) + return x, y + + +loadin_data() +x, y = loadin_data() +#print(x, y) +path = [x, y] + + +def distance(path, i, j): + a = path[0][i]-path[0][j] + b = path[1][i]-path[1][j] + return sqrt(a**2+b**2) + + +# distance_matrix = [] +# for i in range(len(x)): +# distance_matrix.append([]) +# # print(distance_matrix) +# for i in range(2): +# for j in range(len(x)): +# distance_matrix[i].append(distance(path, i, j)) + +# print(distance_matrix[1]) +# print(len(distance_matrix[0])) + + +def exchange(path, a, b): + path[0][a], path[0][b] = path[0][b], path[0][a] + path[1][a], path[1][b] = path[1][b], path[1][a] + + +def sum_distance(path): + sum = 0 + for i in range(len(path[0])-1): + sum += distance(path, i, i + 1) + # print(path) + sum += distance(path, len(path[0]) - 1, 0) + return sum + + + + +ax1 = plt.axes([0,0,1,1]) +# ax2 = plt.axes([0.55,0.05,0.95,0.9]) +fig, ax = plt.subplots() +def draw_line(path): + for j in range(len(path[0])-1): + line1 = [(path[0][j], path[1][j]), (path[0][j+1], path[1][j+1])] + (line1_xs, line1_ys) = zip(*line1) + ax.add_line(Line2D(line1_xs, line1_ys, linewidth=1, color='blue')) + line1 = [(path[0][0], path[1][0]), + (path[0][len(path[0])-1], path[1][len(path[0])-1])] + (line1_xs, line1_ys) = zip(*line1) + ax.add_line(Line2D(line1_xs, line1_ys,linewidth=1, color='blue')) + + +T = 100 +alpha = 0.95 +iters = 1000 +current = sum_distance(path) +print(current, '\n') +next = 0 +count = 0 +xl=[] +yl=[] +plt.cla() +plt.ion() +while(True): + if(T < 0.05): + break + oldcurrent = current + for i in range(iters): + a, b = rd.sample(range(0, len(path[0])), 2) + newpath=[[],[]] + for x,y in zip(path[0],path[1]): + newpath[0].append(x) + newpath[1].append(y) + # print(newpath) + exchange(newpath, a, b) + # print(newpath) + next = sum_distance(newpath) + # print(path) + # print(newpath) + # print(next - current) + if(next < current): + current = next + path = newpath.copy() + elif (rd.random() < exp(-(next - current)/T)): + current = next + path = newpath.copy() + plt.cla() + draw_line(path) + ax.plot(path[0], path[1],'ro') + plt.pause(0.05) + if(oldcurrent!=current): + # print(count) + count += 1 + xl.append(count) + yl.append(current) + ax1.plot(xl,yl) + oldcurrent=current + + T = alpha * T + print(T) +for x,y in zip(path[0],path[1]): + print("(",x,y,")-->",end='') +print(current) +plt.ioff() +plt.show() diff --git a/TSP/testdata/1.txt b/TSP/testdata/1.txt new file mode 100644 index 0000000..6cb2fe9 --- /dev/null +++ b/TSP/testdata/1.txt @@ -0,0 +1,29 @@ +41 49 +35 17 +55 45 +55 20 +15 30 +25 30 +20 50 +10 43 +55 60 +30 60 +20 65 +50 35 +30 25 +15 10 +30 5 +10 20 +5 30 +20 40 +15 60 +45 65 +45 20 +45 10 +55 5 +65 35 +65 20 +45 30 +35 40 +41 37 +64 42 \ No newline at end of file