您好,我在从 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。你可以想象,当我将其应用到我的蚁群系统算法时,结果约为 110 000 公里。这和6千真的不一样。有人可以解释一下我做错了什么吗?
我不熟悉 TSP 常见问题解答中列出的距离计算。 这是我过去使用过的资源:http://www.movable-type.co.uk/scripts/latlong.html
他给出了两种大圆距离计算方法。 两者看起来都不像 TSP 提供的那样。 但是,他们都产生了一个似乎符合现实的距离(Diksa 和 Dikhil 相距约 31k)。
输入数据的单位是千分之一度,我不确定转换为给定的弧度是否考虑到了这一点。
这是一个可能会给您带来更好结果的实现:注意我将输入数据更新为度数:
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)
单位是公里。 球余弦产生大致正确的值。 您使用的代码与您发布的代码相同吗? 请注意,弧度转换似乎没有考虑输入的千分之一度