例如,此GPS坐标数组:
GPSS = [{"Lat":40.641099,"Lon": -73.917094},{"Lat":40.60442,"Lon": -74.054873},{"Lat":40.779582,"Lon": -73.920213},{"Lat":40.651616,"Lon": -73.89097},{"Lat":40.755183,"Lon": -73.846248}]
我已经为每种可能的组合计算了以下距离:
Distances = [{'GPSS': [0, 1], 'Distance': 12.34895151892164}, {'GPSS': [0, 2], 'Distance': 15.380561959360797}, {'GPSS': [0, 3], 'Distance': 2.499303143635897}, {'GPSS': [0, 4], 'Distance': 14.012560598709298}, {'GPSS': [1, 2], 'Distance': 22.53687775052488}, {'GPSS': [1, 3], 'Distance': 14.824576927209662}, {'GPSS': [1, 4], 'Distance': 24.318038568441654}, {'GPSS': [2, 3], 'Distance': 14.423642658224264}, {'GPSS': [2, 4], 'Distance': 6.807346029310139}, {'GPSS': [3, 4], 'Distance': 12.106031672624894}]
0,1 =引用40.641099,-73.917094和40.60442,-74.054873
1,4 = 40.641099,-73.917094和40.755183,-73.846248
我现在想找出访问每个坐标集的最短距离(路线),因此很可能不会是0到1到2到3到4的点。 但是类似1到3到4到2到0。
我将如何完成这样的任务?
据我所知:
for index, d in enumerate(Distances):
print(d['GPSS'])
Total = d['Distance']
Start = d['GPSS'][1] #[0]
CheckPoints = []
CheckPoints.append(d['GPSS'][0])
CheckPoints.append(d['GPSS'][1])
for index2, d2 in enumerate(Distances):
if index != index2:
if Start == d2['GPSS'][0]: #0-1, 1-2, 2-3
Total += d2['Distance']
Start += 1
if d2['GPSS'][0] not in CheckPoints:
CheckPoints.append(d2['GPSS'][0])
if d2['GPSS'][1] not in CheckPoints:
CheckPoints.append(d2['GPSS'][1])
#print(CheckPoints)
print("+"+str(d2['Distance'])+" = "+str(Total)+" | "+str(Start)+" - "+str(d2['GPSS']))
if len(CheckPoints) <= len(GPSS)-1: #GPPS - is from above
for x in range(len(GPSS)-1):
if x not in CheckPoints:
for d3 in Distances:
if d3['GPSS'][0] == x and d3['GPSS'][1] == CheckPoints[-1]:
print("HERE")
print(d3)
Total += d3['Distance']
break
print(Total)
任何帮助将不胜感激。 谢谢
答案 0 :(得分:0)
做您想要的事情的最好方法是创建一个图。如果您不知道这是什么,则应查找它,因为它是非常重要的数据结构。您可能还需要了解什么才能完全理解以下代码。 Python没有内置图,因此您需要创建自己的图。
您需要的图的类型是一个无向加权图,其中所有节点或GPS坐标都相互连接。然后,您可以使用“ Dijkstra算法”的形式对图形进行排序,以找到通往所有点的最短路径。
下面是您所寻找的实现。但是,我将其编码为使用包含配对坐标列表的列表。它还包括一个驱动程序driver(),您可以调用对其进行测试。
我很快就编写了这个文档,没有将其编写为类,但是在现实世界中,您绝对应该这样做。
请注意,在运行驱动程序功能时,它将执行代码并为提供的坐标列表打印出所有可能的路径及其权重。在您的情况下,“重量”是指两点之间的距离。打印的列表显示了用“ 1”表示的路径,该路径指的是坐标列表索引“ 0”处的一对点。列表中的下一个数字是它到下一个的点对。
如果您还有其他问题,请随时提问
from collections import defaultdict
from math import sqrt
# Shortest path to all coordinates from any node
# Coordinates must be provided as a list containing lists of
# x/y pairs. ie [[23.2321, 58.3123], [x.xxx, y.yyy]]
def distance_between_coords(x1, y1, x2, y2):
distance = sqrt(((x2 - x1) ** 2) + ((y2 - y1) ** 2))
return distance
# Adds "names" to coordinates to use as keys for edge detection
def name_coords(coords):
coord_count = 0
for coord in coords:
coord_count += 1
coord.append(coord_count)
return coords
# Creates a weighted and undirected graph
# Returns named coordinates and their connected edges as a dictonary
def graph(coords):
coords = name_coords(coords)
graph = defaultdict(list)
edges = {}
for current in coords:
for comparer in coords:
if comparer == current:
continue
else:
weight = distance_between_coords(current[0], current[1],
comparer[0], comparer[1])
graph[current[2]].append(comparer[2])
edges[current[2], comparer[2]] = weight
return coords, edges
# Returns a path to all nodes with least weight as a list of names
# from a specific node
def shortest_path(node_list, edges, start):
neighbor = 0
unvisited = []
visited = []
total_weight = 0
current_node = start
for node in node_list:
if node[2] == start:
visited.append(start)
else:
unvisited.append(node[2])
while unvisited:
for index, neighbor in enumerate(unvisited):
if index == 0:
current_weight = edges[start, neighbor]
current_node = neighbor
elif edges[start, neighbor] < current_weight:
current_weight = edges[start, neighbor]
current_node = neighbor
total_weight += current_weight
unvisited.remove(current_node)
visited.append(current_node)
return visited, total_weight
def driver():
coords = [[1.7592675, 92.4836507], [17.549836, 32.457398],
[23.465896, 45], [25.195462, 37.462742],
[42.925274, 63.234028], [2.484631, 5.364871],
[50.748376, 36.194797]]
coords, edges = graph(coords)
shortest_path(coords, edges, 3)
shortest_path_taken = []
shortest_path_weight = 0
for index, node in enumerate(coords):
path, weight = shortest_path(coords, edges, index + 1)
print('--------------------------------------')
print("Path", index + 1, "=", path)
print("Weight =", weight)
if index == 0:
shortest_path_weight = weight
shortest_path_taken = path
elif weight < shortest_path_weight:
shortest_path_weight = weight
shortest_path_taken = path
print('--------------------------------------')
print("The shortest path to all nodes is:", shortest_path_taken)
print("The weight of the path is:", shortest_path_weight)
编辑: 这是调用驱动程序函数时的输出结果:
--------------------------------------
Path 1 = [1, 5, 3, 4, 2, 7, 6]
Weight = 386.3252849770695
--------------------------------------
Path 2 = [2, 4, 3, 6, 7, 5, 1]
Weight = 189.3710721663407
--------------------------------------
Path 3 = [3, 4, 2, 5, 7, 6, 1]
Weight = 173.99235180101968
--------------------------------------
Path 4 = [4, 3, 2, 7, 5, 6, 1]
Weight = 172.86112533927678
--------------------------------------
Path 5 = [5, 3, 7, 4, 2, 1, 6]
Weight = 247.08415835699554
--------------------------------------
Path 6 = [6, 2, 4, 3, 7, 5, 1]
Weight = 330.1567215845902
--------------------------------------
Path 7 = [7, 4, 5, 3, 2, 6, 1]
Weight = 247.70066871941674
--------------------------------------
The shortest path to all nodes is: [4, 3, 2, 7, 5, 6, 1]
The weight of the path is: 172.86112533927678
[Finished in 0.1s]*