TSP with 退火

master
徐涛 3 years ago
parent 26b73f4a1b
commit 719474fde4

@ -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()

29
TSP/testdata/1.txt vendored

@ -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
Loading…
Cancel
Save