求解TSP问题神器——elkai(简单好用)

elkai是python的第三方库,专门用于解决TSP问题,目前已知能够在规模达到315个节点的问题中求解出最优方案。elkai本身的实现基于大名鼎鼎的LKH算法,该算法被认为是目前解决TSP问题最有效的算法之一。

elkai的调用过程很简单,只需要构建好并传入各节点的距离矩阵,就能返回最优解决方案

下载方式:

cmd中输入:pip install elkai

本文利用规模为101个点的TSP问题做例子进行介绍

点的数据如下:

idx_coordy_coord
14050
22585
………………
1013167

各点示意图如下:

 

 编写函数计算各点间的距离矩阵:

# 计算距离矩阵,此处用坐标直接计算距离,实际交通规划中可能会有现成的距离矩阵
    def genDistanceMat(x, y):
        X = np.array([x, y])
        distMat = ssp.distance.pdist(X.T)
        distMat = ssp.distance.squareform(distMat)
        return distMat

编写函数计算整个路线的总长度:

# 计算所得方案的线路总长度
    def cal_fitness(sol):
        tot_len = np.sum(distance[sol[:-1], sol[1:len(sol)]])
        return tot_len

主程序如下:

def main(city_condition):
    # 计算距离矩阵,此处用坐标直接计算最短距离,实际交通规划中可能会有现成的最短距离矩阵
    def genDistanceMat(x, y):
        X = np.array([x, y])
        distMat = ssp.distance.pdist(X.T)
        distMat = ssp.distance.squareform(distMat)
        return distMat

    x, y = city_condition[:, 0], city_condition[:, 1]
    distance = genDistanceMat(x, y)

    # 计算所得方案的线路总长度
    def cal_fitness(sol):
        tot_len = np.sum(distance[sol[:-1], sol[1:len(sol)]])
        return tot_len

    sol = elkai.solve_int_matrix(distance)
    # sol = elkai.solve_float_matrix(distance,runs=10)#允许浮点距离
    sol.append(0)
    '''这个函数计算出的是有回路的TSP问题,但返回的解方案sol没有给出完整解方案(少一个终点0),故我们在代码中在解方案最末尾加上了编号0'''

    print("最优解方案:", sol)
    print("最优解总长度:", cal_fitness(sol))
    return sol,cal_fitness(sol)

主程序输入城市的x,y坐标,输出即为TSP问题的解方案和总长度,输入无误则可直接跑,使用十分方便。调用elkai解TSP不仅能够得到非常好的解方案,同样用时也很少(其中一个原因是该库用的C语言编译封装实现的)。

求解结果如下图:

 

所有程序代码:

'利用elkai求解TSP问题'
'2022.6.22 北京交通大学 韬会'

import numpy as np
import elkai
import math
import matplotlib.pyplot as plt
import scipy as sp
import scipy.spatial as ssp
import pandas as pd

data = pd.read_excel('cvrp.xlsx')
num_node = len(data.id)
loc=[[data.x_coord[i],data.y_coord[i]]    for i in range(num_node)]
loc=np.array(loc)
print(loc)
x,y = loc[:,0],loc[:,1]
plt.scatter(list(x),list(y))


def main(city_condition):
    # 计算距离矩阵,此处用坐标直接计算最短距离,实际交通规划中可能会有现成的最短距离矩阵
    def genDistanceMat(x, y):
        X = np.array([x, y])
        distMat = ssp.distance.pdist(X.T)
        distMat = ssp.distance.squareform(distMat)
        return distMat

    x, y = city_condition[:, 0], city_condition[:, 1]
    distance = genDistanceMat(x, y)

    # 计算所得方案的线路总长度
    def cal_fitness(sol):
        tot_len = np.sum(distance[sol[:-1], sol[1:len(sol)]])
        return tot_len

    sol = elkai.solve_int_matrix(distance)
    # sol = elkai.solve_float_matrix(distance,runs=10)#允许浮点距离
    sol.append(0)
    '''这个函数计算出的是有回路的TSP问题,但返回的解方案sol没有给出完整解方案(少一个终点0),故在解方案最末尾加上了编号0'''

    print("最优解方案:", sol)
    print("最优解总长度:", cal_fitness(sol))
    return sol,cal_fitness(sol)


sol,lenth=main(loc)


# 绘图部分
plt.scatter(x,y)
for i in range(len(x)):
    plt.annotate(sol[i], xy = (x[i], y[i]), xytext = (x[i]+0.3, y[i]+0.3)) # 这里xy是需要标记的坐标,xytext是对应的标签坐标
plt.plot(x,y)
plt.show()

参考文献:

https://mp.weixin.qq.com/s/BWJV_-mtmBK0_Tn4Kznapw

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值