模拟退火算法,顾名思义,模拟晶体退火过程。晶体在加热后固体化为液态,内部原子运动加剧,会离开原有位置向四周扩散。此时慢慢进行退火冷却使其重新固化,粒子往往会停留在比原先能量低得多的位置上,本质上也是通过随机性跳出局部最优。
本文尝试用模拟退火算法对TSP问题(travelling salesman problem)进行求解,并与Gurobi求解器进行对比。

Ω

TSP:旅行推销员问题
旅行推销员是一个非常经典的NP-Hard问题,即在多项式时间内也无法验证解的正确性。问题大意非常简单,就是有个城市,两两之间距离已知,有个salesman从某个城市出发希望能够游历其他每座城市一遍,同时最后回到出发城市,重度强迫症患者的他希望设计出一条满足上述要求的最短路线。
如果你是他的朋友,你会如何劝退他,请写一篇不少于200词的感化信。(100)
✦ 初始化城市坐标和距离矩阵
可以通过随机生成或者加载之前生成的坐标来初始化
import numpy as np
import random as rd
# 随机生成城市坐标
loc = np.zeros([100, 2])
for i in range(len(loc)):
loc[i] = (rd.random() * 100, rd.random() * 100)
np.save("loc.npy", loc) # 保存生成坐标
# 导入之前城市坐标
# loc=np.load("loc.npy")
num = len(loc)
# 多一列方便处理回到原城市的约束
dist = np.zeros([num, num + 1])
# 计算距离矩阵
for i in range(num):
for j in range(i + 1, num):
dist[i, j] = dist[j, i] = np.linalg.norm(loc[i] - loc[j])
dist[:, num] = dist[:, 0]
✦ 贪心求初始解
TSP问题的解基本不需要编码,包含所有城市一个全排列的列表就可以作为可行解的编码。我这里规定了0号作为起点和终点。
用贪心算法构造初始解,即从起点城市开始每次选择离当前城市最近的且还未访问过的城市作为下一个目的地。在城市数较少时贪心结果几乎就是最优解,城市数大了就嘻嘻。
# 贪心求初始解
path=[0]
isVisited=[False]*num
isVisited[0]=True
crt=0
sum_d=0
for i in range(num):
idx=np.argsort(dist[crt])
for j in idx:
if j!=num and not isVisited[j] and j!=crt:
path.append(j)
sum_d+=dist[crt,j]
isVisited[j]=True
crt=j
break
path.append(0)
sum_d

本文探讨了使用模拟退火算法解决旅行商问题(TSP),并通过与Gurobi求解器的对比展示了解决方案的有效性和效率。
最低0.47元/天 解锁文章
481

被折叠的 条评论
为什么被折叠?



