import numpy as np
import matplotlib.pyplot as plt
import math
def getdistMat(coordinates):
num = coordinates.shape[0]
distmat = np.zeros((num, num))
for i in range(num):
for j in range(i, num):
if i==j:
distmat[i][j] =10000
else:
distmat[i][j] = distmat[j][i] = np.linalg.norm(coordinates[i] - coordinates[j])
return distmat
def initPara():
tInitial = 1000.0
tFinal = 1.0
nMarkov = 1000
alpha = 0.99
return tInitial, tFinal, alpha, nMarkov
def drawtour(tourGiven, value, coordinates,nameCity):
fig = plt.figure()
num = len(tourGiven)
plt.title("Optimization result of TSP{:d}".format(num))
plt.rcParams['font.sans-serif'] = [u'SimHei']
plt.rcParams['axes.unicode_minus'] = False
x0, y0 = coordinates[tourGiven[num - 1]]
x1, y1 = coordinates[tourGiven[0]]
plt.scatter(int(x0), int(y0), s=15, c='g')
plt.plot([x1, x0], [y1, y0], c='r')
for i in range(num - 1):
x0, y0 = coordinates[tourGiven[i]]
x1, y1 = coordinates[tourGiven[i + 1]]
plt.text(int(x0), int(y0),nameCity[tourGiven[i]], ha='center', va='bottom', fontsize=10.5)
plt.scatter(int(x0), int(y0), s=15, c='r')
plt.plot([x1, x0], [y1, y0], c='b')
plt.xlabel("Total mileage of the tour:{:.1f}".format(value))
plt.show()
def drawiter(recordNow, recordBest, recordNew):
fig = plt.figure()
plt.title("Distance iteration graph")
plt.plot(np.array(recordNow), 'g-', label='Now')
plt.plot(np.array(recordNew), 'b-', label='New')
plt.plot(np.array(recordBest), 'r-', label='Best')
plt.xlabel("Number of iterations")
plt.ylabel("Distance value")
plt.legend()
plt.show()
def calTourMileage(tourGiven, nCity, distMat):
tourMileage = 0
for i in range(nCity - 1):
tourMileage += distMat[tourGiven[i], tourGiven[i + 1]]
tourMileage += distMat[tourGiven[nCity - 1], tourGiven[0]]
return round(tourMileage)
def greedy(distMat, start_index):
sum_distance, seq_result, n = 0, [start_index, ], len(distMat)
for path_index in range(n - 1):
distance_list = distMat[start_index]
min_dis = max(distance_list)
for index, distance in enumerate(distance_list):
if (index not in seq_result) and (distance < min_dis):
min_dis = distance
start_index = index
sum_distance += min_dis
seq_result.append(start_index)
return sum_distance, seq_result
def mutateSwap(tourGiven, nCity):
if np.random.rand() > 0.5:
while True:
loc1 = np.int(np.ceil(np.random.rand() * (nCity - 1)))
loc2 = np.int(np.ceil(np.random.rand() * (nCity - 1)))
if loc1 != loc2:
break
tourGiven[loc1], tourGiven[loc2] = tourGiven[loc2], tourGiven[loc1]
else:
while True:
loc1 = np.int(np.ceil(np.random.rand() * (nCity - 1)))
loc2 = np.int(np.ceil(np.random.rand() * (nCity - 1)))
loc3 = np.int(np.ceil(np.random.rand() * (nCity - 1)))
if ((loc1 != loc2) & (loc2 != loc3) & (loc1 != loc3)):
break
if loc1 > loc2:
loc1, loc2 = loc2, loc1
if loc2 > loc3:
loc2, loc3 = loc3, loc2
if loc1 > loc2:
loc1, loc2 = loc2, loc1
tourTmp = tourGiven[loc1:loc2].copy()
tourGiven[loc1:loc3 - loc2 + 1 + loc1] = tourGiven[loc2:loc3 + 1].copy()
tourGiven[loc3 - loc2 + 1 + loc1:loc3 + 1] = tourTmp.copy()
return tourGiven
def main():
city_name = []
coordinates = []
with open('18城市坐标.txt', 'r', encoding='UTF-8') as f:
lines = f.readlines()
for line in lines:
line = line.split('\n')[0]
line = line.split(',')
city_name.append(line[0])
coordinates.append([float(line[1]), float(line[2])])
coordinates = np.array(coordinates)
nCity = coordinates.shape[0]
distMat = getdistMat(coordinates)
tourNew = np.arange(nCity)
tourNow = np.arange(nCity)
valueNow = 0
valueNow = calTourMileage(tourNow, nCity, distMat)
tourBest = tourNow.copy()
print(valueNow, tourNow)
valueBest = valueNow
valueNew = 0
recordBest = []
recordNow = []
recordNew = []
tInitial, tFinal, alpha, nMarkov = initPara()
nMarkov = nCity
tNow = tInitial
while tNow > tFinal:
for i in np.arange(nMarkov):
mutateSwap(tourNew, nCity)
valueNew = calTourMileage(tourNew, nCity, distMat)
deltaE = valueNew - valueNow
if deltaE < 0:
tourNow = tourNew.copy()
valueNow = valueNew
if valueNew < valueBest:
valueBest = valueNew
tourBest = tourNew.copy()
else:
if np.random.rand() < np.exp(-(deltaE) / tNow):
valueNow = valueNew
tourNow = tourNew.copy()
else:
tourNew = tourNow.copy()
tNow = alpha * tNow
recordBest.append(valueBest)
recordNow.append(valueNow)
recordNew.append(valueNew)
drawtour(tourBest, valueBest, coordinates,city_name)
drawiter(recordNow, recordBest, recordNew)
print("路线: \n", tourBest)
print("里程: {:.1f}".format(valueBest))
if __name__ == '__main__':
main()
![计算迭代图
|