问题描述
我尝试优化一个简单的python算法,该算法可以大致解决Traveling Salesman问题:
import math
import random
import matplotlib.pyplot as plt
import datetime
#Distance between two point
def distance(point1,point2):
return math.sqrt((point2[0]-point1[0])**2+(point2[1]-point1[1])**2)
#TSP TimeTraveler Algorithm
def TSP_TimeTraveler(Set_Points):
print("Solving TSP")
#For calculating execution time
time_start = datetime.datetime.now()
#Copy the set points
points = Set_Points.copy()
route = []
#Take 3 points at random
route.append(points.pop(random.randint(0,len(points)-1)))
route.insert(0,points.pop(random.randint(0,len(points)-1)))
route.insert(1,len(points)-1)))
#Calulating the initial route length
Length = distance(route[0],route[1]) + distance(route[1],route[-1]) + distance(route[-1],route[0])
#Time Traveler Algorithm
while len(points)>0 :
print("Points left : ",len(points),' ',end="\r")
#Take a random point from the Set
point = points.pop(random.randint(0,len(points)-1))
###############################################################################################################
#### Finding the closest route segment by calculation all lengths posibilities and finding the minimum one ####
###############################################################################################################
Set_Lengths = []
for i in range(1,len(route)):
#Set of Lengths when the point is on each route segment except the last one
L = Length - distance(route[i-1],route[i]) + distance(route[i-1],point) + distance(point,route[i])
Set_Lengths.append((i,L))
#Adding the last length when the point is on the last segement
L = Length - distance(route[-1],route[0]) + distance(route[-1],route[0])
Set_Lengths.append((0,L))
###############################################################################################################
###############################################################################################################
#Sorting the set of lengths
Set_Lengths.sort(key=lambda k: k[1])
#Inserting the point on the minimum length segment
route.insert(Set_Lengths[0][0],point)
#Updating the new route length
Length = Set_Lengths[0][1]
#Connecting the start point with the finish point
route.append(route[0])
#For calculating execution time
time_end = datetime.datetime.now()
delta = (time_end-time_start).total_seconds()
print("Points left : ",' Done ',)
print("Execution time : ",delta,"secs")
return route
#######################
#Testing the Algorithm#
#######################
#Size of the set
size = 2520
#Generating a set of random 2D points
points = []
for i in range(size):
points.append([random.uniform(0,100),random.uniform(0,100)])
#Solve TSP
route = TSP_TimeTraveler(points)
#Plot the solution
plt.scatter(*zip(*points),s=5)
plt.plot(*zip(*route))
plt.axis('scaled')
plt.show()
该算法分为三个简单步骤:
1 /第一步,我从设置的点中随机抽取3个点,并将它们连接为初始路线。
2 /然后接下来的每一步,我从剩下的点集中随机取一个点。并尝试找到我拥有的路线的最接近的路段并将其连接到路段。
3 /我一直重复步骤2 /,直到剩下的点集为空。
以下是该算法如何求解一组120点的图像:TimeTravelerAlgorithm.gif
我将其命名为“ Time Traveler”,因为它的运行方式类似于贪婪的推销员算法。但是,贪婪的推销员不是去当前最接近的新城市,而是去过去已去过的最近城市,去拜访那个新城市,然后继续他的正常路线。
时间旅行者开始了3个城市的路线,并且旅行者过去的每一步都添加了一个新城市,直到到达现在为止,他参观了所有城市并返回了自己的城市。
该算法可针对少量点快速提供体面的解决方案。这是每套设备的执行时间,所有设备都是在2.6GHz双核Intel Core i5处理器Macbook上完成的:
- 在0.03秒内获得120点
- 在0.23秒内获得360分
- 约25秒获得2520分
- 在3分钟内获得10000点 在大约5小时内
- 100,000点(Solution Map)
该算法远未优化,因为在某些情况下,它给出的交叉路径不是最佳的。而且都是用纯python制作的。也许使用numpy或一些高级库甚至GPU都可以加快程序的速度。
我希望您的评论对如何优化它有所帮助。我试图在没有交叉路线的情况下近似解决可能非常大的点集(从100万到1000亿点)。
PS:我的算法和代码已打开。来自互联网的人们可以随时在任何项目或任何研究中使用它。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)