优化旅行推销员算法时间旅行算法

问题描述

我尝试优化一个简单的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 (将#修改为@)