【问题标题】:Find the Shortest Distance between sets of GPS Coordinates - Python查找 GPS 坐标集之间的最短距离 - Python
【发布时间】:2019-12-07 20:46:18
【问题描述】:

例如这个 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)

任何帮助将不胜感激。 谢谢

【问题讨论】:

  • 查找dijkstra的算法
  • @user1558604 这不是旅行商问题吗? - op想要访问每组坐标,而不仅仅是最短路径

标签: python arrays gps coordinates distance


【解决方案1】:

完成您所寻找的工作的最佳方式是创建一个图表。如果您不知道那是什么,您应该查找它,因为它是一个非常重要的数据结构。您可能还需要知道它是什么才能完全理解以下代码。 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]*

【讨论】:

  • 你好。我不一定说你错了,但是当我实现算法时,我得到了一些值。我不确定我们中的哪一个是错的。有什么见解吗? -------------------------------------- 路径 1 = [1, 5, 3, 4, 2, 6, 7] 权重 = 182.30775878123 -------------------------------------------------- 路径 2 = [2, 4, 3, 5, 7, 6, 1] 权重 = 216.078999832647 -------------------------------- ------ 路径 3 = [3, 4, 2, 6, 7, 5, 1] 权重 = 183.788612031565 ------------------------ --------------- 路径 4 = [4, 3, 2, 6, 7, 5, 1] 权重 = 188.518109747981
  • 路径 5 = [5, 3, 4, 2, 6, 7, 1] 权重 = 206.429943633481 --------- ----------------- 路径 6 = [6, 2, 4, 3, 5, 7, 1] 权重 = 177.307960493246 ------------ -------------------------- 路径 7 = [7, 4, 3, 2, 6, 5, 1] 权重 = 199.283555617923 --- ----------------------------------- 所有节点的最短路径是:[6, 2, 4, 3, 5, 7, 1] 路径的权重为:177.307960493246 ---------------------------------- ----
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-06
  • 2020-08-06
  • 1970-01-01
  • 2021-01-08
  • 2022-06-10
相关资源
最近更新 更多