【问题标题】:Calculating distances in TSPLIB在 TSPLIB 中计算距离
【发布时间】:2018-09-20 01:59:07
【问题描述】:

您好,我从 tsp 库计算城市之间的距离时遇到问题:http://www.math.uwaterloo.ca/tsp/world/countries.html。我有这组数据(吉布提的城市):http://www.math.uwaterloo.ca/tsp/world/dj38.tsp。我在这里使用此函数计算此 QaA 中的距离:http://comopt.ifi.uni-heidelberg.de/software/TSPLIB95/TSPFAQ.html。我用python编写了这个,现在看起来像这样,这是我的代码:

cityCoords = {
    1:(11003.611100,42102.500000),
    2:(11108.611100,42373.888900),
    3:(11133.333300,42885.833300),
    4:(11155.833300,42712.500000),
    5:(11183.333300,42933.333300),
    6:(11297.500000,42853.333300),
    7:(11310.277800,42929.444400),
    8:(11416.666700,42983.333300),
    9:(11423.888900,43000.277800),
    10:(11438.333300,42057.222200),
    11:(11461.111100,43252.777800),
    12:(11485.555600,43187.222200),
    13:(11503.055600,42855.277800),
    14:(11511.388900,42106.388900),
    15:(11522.222200,42841.944400),
    16:(11569.444400,43136.666700),
    17:(11583.333300,43150.000000),
    18:(11595.000000,43148.055600),
    19:(11600.000000,43150.000000),
    20:(11690.555600,42686.666700),
    21:(11715.833300,41836.111100),
    22:(11751.111100,42814.444400),
    23:(11770.277800,42651.944400),
    24:(11785.277800,42884.444400),
    25:(11822.777800,42673.611100),
    26:(11846.944400,42660.555600),
    27:(11963.055600,43290.555600),
    28:(11973.055600,43026.111100),
    29:(12058.333300,42195.555600),
    30:(12149.444400,42477.500000),
    31:(12286.944400,43355.555600),
    32:(12300.000000,42433.333300),
    33:(12355.833300,43156.388900),
    34:(12363.333300,43189.166700),
    35:(12372.777800,42711.388900),
    36:(12386.666700,43334.722200),
    37:(12421.666700,42895.555600),
    38:(12645.000000,42973.333300)
    }

def calcCityDistances(coordDict):
    cities = list(coordDict.keys())
    n = len(cities)
    distances = {}
    latitude = []
    longitude = []
    RRR = 6378.388;
    PI = 3.141592;

    for i in range(1,n+1):
        cityA = cities[i-1]
        latA, longA = coordDict[cityA]
        deg = int(latA)
        Min = latA - deg
        latitude.append(PI * (deg + 5 * Min / 3) / 180)
        deg = int(longA);
        Min = longA - deg;
        longitude.append(PI * (deg + 5 * Min / 3) / 180)

    for i in range(1,n+1):
        for j in range(i + 1, n + 1):
            q1 = cos(longitude[i-1] - longitude[j-1]);
            q2 = cos(latitude[i-1] - latitude[j-1]);
            q3 = cos(latitude[i-1] + latitude[j-1]);
            key = frozenset((i, j))
            distances[key] = {}
            dist = RRR * acos(0.5 * ((1.0 + q1) * q2 - (1.0 - q1) * q3)) + 1.0  
            distances[key]['dist'] = dist
            distances[key]['pher'] = init_fer
            distances[key]['vis'] = 0

    return  distances 

distances = calcCityDistances(cityCoords)

我的问题是,在这个算法中计算出的距离非常大。城市之间的一条路线的平均长度是 10 000 公里,问题是最佳 TSP 路线是 6635。您可以想象,当我将其应用于我的 Ant Colony System 算法时,结果约为 110 000 公里。这和6千真的不一样。有人可以解释一下我做错了什么吗?

【问题讨论】:

  • 我刚刚遇到了同样的问题。我相信官方的公式是错误的:“纬度[i] = PI * (deg + 5.0 * min / 3.0 ) / 180.0”。部分 5.0*min/3.0 是将分钟转换为小数。 60 分钟将是 1 位小数。如果不是除以 3.0 而是除以 300,就会出现这种情况。所以正确的公式是“PI * (deg + 5.0 * min / 300) / 180.0”

标签: python distance traveling-salesman lib


【解决方案1】:

我不熟悉 TSP 常见问题解答中列出的距离计算。这是我过去使用的资源:@​​987654321@

他给出了两种很好的圆距计算方法。两者看起来都不像提供的 TSP。但是,他们都产生了一个似乎与现实相符的距离(Diksa 和 Dikhil 相距大约 31k)。

输入数据是 1000 度,我不确定转换为给定的弧度是否考虑到了这一点。

这是一个可能会给您带来更好结果的实现:注意我将输入数据更新为度数:

import cmath
import math

cityCoords = {
    1:(11.0036111,42.1025),
    2:(11.1086111,42.3738889)
    }

def spherical_cosines(coordDict):
    R = 6371;  # kilometers
    cities = list(coordDict.keys())
    n = len(cities)
    for i in range(1,n+1):
        for j in range(i + 1, n + 1):
            cityA = cities[i-1]
            lat1, lon1 = coordDict[cityA]
            cityB = cities[j-1]
            lat2, lon2 = coordDict[cityB]
            lat1_radians = math.radians(lat1)
            lat2_radians = math.radians(lat2)
            lon1_radians = math.radians(lon1)
            lon2_radians = math.radians(lon2)
            print('A={},{} B={},{}'.format(lat1_radians, lon1_radians, lat2_radians, lon2_radians))
            delta_lon_radians = math.radians(lon2-lon1)
            distance = cmath.acos(cmath.sin(lat1_radians) * cmath.sin(lat2_radians) + cmath.cos(lat1_radians) *
                        math.cos(lat2_radians) * cmath.cos(delta_lon_radians)) * R;
            print('spherical_cosines distance={}'.format(distance))


spherical_cosines(cityCoords)

更新: 您发布的代码没有产生正确的距离值。这是使用 calcCityDistances 和球余弦的前两个城市:

input loc=11003.6111, 42102.5
input loc=11108.6111, 42373.8889
radians A = 192.05631381917777,734.8329132074075
B=193.88890915251113,739.5740671363777
calcCityDistances distance = 8078.816781077703
input degrees A=11.0036111,42.1025 B=11.1086111,42.3738889
radians A=0.19204924330399503,0.7348272483209126
B=0.19388183901858905,0.7395638781792782
spherical_cosines> distance=(31.835225475974934+0j)

单位是公里。球余弦产生近似正确的值。您使用的代码与您发布的代码相同吗?请注意,弧度转换似乎没有考虑到输入是千分之一度

【讨论】:

  • 谢谢你的回答 :) 但这并不能解决我的问题,因为你的算法给出了与我的城市之间相同的距离单位,所以 TSP 的结果将是相同的
  • 两种方法的值不同。我用显示我得到的输出更新了答案
  • 是的,你是对的,我用谷歌地图检查了你的计算,距离是正确的。谢谢。这里的问题是,为什么他们有最佳路径 6656,因为这些距离我的程序计算出的最佳路径 845.171608273 与他们的结果相差甚远
  • 您在 845 公里的正确轨道上。我从 38 个点创建了一个 KML 文件,然后在 GE 中通过它们做了一个非常粗糙的路径,得到了 876 公里。网站上给出的距离计算有两个问题:首先,我不认为它需要千分之一度的输入。您可以通过转换为弧度来判断这是不正确的。三角函数必须有弧度。其次,即使你给距离计算函数度数(并且弧度计算正确),距离很近但不正确(50公里 31公里)
猜你喜欢
  • 2021-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-19
  • 2014-08-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多