简体   繁体   English

Python中Dijkstra算法在真实地图上的最短路径

[英]Shortest path on real maps by Dijkstra's algorithm in python

I'm trying to find the shortest path between two spots on the real map by Dijkstra's algorithm, but I cannot get a result in a limited time(120s). 我正在尝试使用Dijkstra的算法在真实地图上找到两个地点之间的最短路径,但是我无法在有限的时间内(120秒)获得结果。 How do I optimize my code? 如何优化代码? I'm only permitted to use "pillow" as an external package. 我只允许使用“枕头”作为外部包装。

There are two red spots(33, 193)(749, 457) on the map , and I want to draw the shortest path of them. 这里是两个红点(33,193)(749,457) 的地图 ,我想吸引他们的最短路径。 But it cannot put a result even if taking a long time. 但是即使花费很长时间也无法取得结果。 I test my Dijkstra's algorithm well, and don't know if it still has many bugs. 我已经很好地测试了Dijkstra的算法,并且不知道它是否还有很多错误。 The Dijkstra's algorithm is created with same distance -- 1. Dijkstra的算法是用相同的距离创建的-1。

Here is the complete code. 是完整的代码。

def walkback(P, x, y):
    L = [y]
    while x != y:
        y = P[y]
        L = [y] + L
    return L

def path(A, x, y):
    M = []
    W = [x]
    P = {}
    while W != []:
       u = W.pop()
       if u == y:
            return walkback(P, x, y)
       M.append(u)
       for v in A[u]:
           if not v in M:
               P[v] = u
               W.append(v)
    return None

This is the Dijkstra's algorithm. 这就是Dijkstra的算法。 And I tested it for this. 我为此进行了测试。

A = { 1.324: [2,5.24], 2: [1.324,6], 3: [2],
      4: [5],   5.24: [2,6], 6: [3] }
print(path(A, 1.324, 6))
print(path(A, 1.324, 4))

For any pixel, the white and the red(start, end) are movable points, and set to 0. Other colors are set to 1. 对于任何像素,白色和红色(开始,结束)是可移动的点,并设置为0。其他颜色设置为1。

for x in range(0, w):
    for y in range(0, h):
        (r, g, b, a) = im.getpixel((x, y))
        if (r, g, b) == (255, 0, 0):
            Red.append((x, y))
            arr[y][x] = 0
        elif (r, g, b) == (255, 255, 255):
            arr[y][x] = 0
        else:
            arr[y][x] = 1

And this created a graph for any movable spot. 这就为任何活动点创建了一个图形。 For ['0.1': ['0.2', '0.3']], it means you can move to (0, 2) and (0, 3) from (0, 1). 对于['0.1':['0.2','0.3']],这意味着您可以从(0,1)移至(0,2)和(0,3)。

def coord2num(x, y):
    z = str(x) + "." + str(y)
    return z

B = {}
for x in range(0, h):
    for y in range(0, w):
        if arr[x][y] != 0:
            continue
        key = coord2num(x, y)
        B[key] = []
        if x - 1 >= 0 and arr[x - 1][y] == 0:
            value = coord2num(x - 1, y)
            B[key].append(value)
        if x + 1 < h and arr[x + 1][y] == 0:
            value = coord2num(x + 1, y)
            B[key].append(value)
        if y + 1 < w and arr[x][y + 1] == 0:
            value = coord2num(x, y + 1)
            B[key].append(value)
        if y - 1 >= 0 and arr[x][y - 1] == 0:
            value = coord2num(x, y - 1)
            B[key].append(value)

I expect the output of the shortest path, but it still run out of time. 我期望最短路径的输出,但是仍然用完时间。

Is it compulsory that you use Dijkstra? 您必须使用Dijkstra吗? It looks like using an A* approach would be better here, since you can easily design a good heuristic (manhattan distance for instance). 看起来这里使用A *方法会更好,因为您可以轻松设计出良好的启发式方法(例如,曼哈顿距离)。

This would probably solve your time restrictions problem. 这可能会解决您的时间限制问题。 Also, on a real map you should clarify how your graph is defined (do you only account for intersection? And if not, how do you cut space?). 另外,在真实地图上,您应该阐明图形的定义方式(您仅考虑交集吗?否则,如何削减空间?)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM