【发布时间】:2021-02-16 18:03:08
【问题描述】:
我是一名初学者,但仍在掌握路径算法的概念。我们的教授给了我们这个问题,在线法官将评估哪个解决方案:
我得到以下信息:
- 节点数
L(每个节点以数字命名,1-indexed)2 <= L <= 1000
- 从一个节点到另一个节点的有向边
R,以及边的成本C0 <= R <= L * sqrt(L)1 <= C <= 100- 边数与节点数一起给出,以便轻松收集有向边。
- 没有负成本。
- 源节点A
- 目的节点B
- 遍历的节点X
我需要找出从 A 到 X 到 B 的最短路径的成本。
我的代码运行如下:
- 获取输入。
- 生成图的邻接表。
- 获取 A、X 和 B。
- 获取 A 和 X 之间最短路径的成本
ax。 - 获取 X 和 B 之间最短路径的成本
xb。 - 从 A 到 X 到 B 的最短路径的成本
axb是ax + xb。
法官认为这个解决方案超过了 1 秒的时间限制。有没有办法改进它并提高效率?
-
我考虑过将 X 设为源节点,但该图是有向的,而取消指向它会产生错误的结果。
-
我考虑过检查 A 和 X 之间的路径是否存在,然后是 X 和 B,但它似乎对性能的影响可以忽略不计。
-
我还考虑过“钳制”图表,使其仅包含 A 和 B 之间经过 X 的路径,但我不知道如何以最有效的方式做到这一点。
-
我尝试过应用this idea,但它只是让它运行时间更长。
-
我的教授说 A* 对他给我们提出的问题来说太过分了,但如果我为此找到一个启发式方法,也许我会考虑使用它。
-
我尝试了 Floyd-Warshall 算法,但它使代码消耗了更多的时间和内存——但有件事告诉我这个算法可以优化:
def shortestPath(dist, i, j, k): # My first try in applying the Floyd-Warshall Algorithm
for k in range(len(dist)):
for i in range(len(dist)):
for j in range(len(dist)):
if dist[i][j] > dist[i][k] + dist[k][j]:
dist[i][j] = dist[i][k] + dist[k][j]
# Graph construction and algorithm application:
.
.
.
# generate adjacency list of the graph
graph = [[math.inf for node_x in range(nodes)] for node_y in range(nodes)]
next = [[None for node_x in range(nodes)] for node_y in range(nodes)]
for node in range(nodes):
graph[node][node] = 0
for edge in range(edges):
node_a, node_b, cost = input().split()
node_a = int(node_a) - 1
node_b = int(node_b) - 1
cost = eval(cost)
graph[node_a][node_b] = cost
next[node_a][node_b] = node_b
i, k, j = input().split() # get source, traversed and destination node
i = int(i) - 1
j = int(j) - 1
k = int(k) - 1
shortestPath(graph, i, j, k)
ikj = graph[i][j]
if ikj == math.inf: # path nonexistent if either ax or xb is infinite
out.append("path nonexistent")
continue
else:
out.append(ikj)
这是我的代码:
import heapq
import math
# tools start here
def dijkstra(G, S):
pq = []
costs = {v: math.inf for v in G}
costs[S] = 0
heapq.heappush(pq, (0, S))
while pq:
d_u, u = heapq.heappop(pq)
for e in G[u]:
v, w = e
d_v = costs[v]
if d_v > d_u + w: # relaxation operation
costs[v] = d_u + w
heapq.heappush(pq, (d_u + w, v))
return costs
# tools end here
t = int(input()) # get number of test cases
out = [] # initialize output array
for _ in range(t): # for each test case
# get input
nodes, edges = input().split()
nodes = int(nodes)
edges = int(edges)
# generate adjacency list of the graph
graph = {}
for node in range(1, nodes + 1):
graph[str(node)] = []
for edge in range(edges):
node_a, node_b, cost = input().split()
cost = eval(cost)
graph[node_a].append((node_b, cost,))
a, x, b = input().split() # get source, traversed and destination node
ax = dijkstra(graph, a)[x] # get shortest path cost from a to x
xb = dijkstra(graph, x)[b] # get shortest path cost from x to b
axb = ax + xb # add the path costs
if axb == math.inf: # path nonexistent if either ax or xb is infinite
out.append("path nonexistent")
continue
else:
out.append(axb)
[print(_) for _ in out] # print output array
这里是示例输入:
2
3 2
1 2 1
2 3 1
1 2 3
3 1
1 2 1
1 2 3
这是示例输出:
2
path nonexistent
【问题讨论】:
-
如果没有一些示例输入,很难理解您的问题。请编辑您的问题并显示生成的输入和输出的示例。
-
真正的问题是什么?根据这个问题,您似乎已经解决了您的问题,但只是希望它更快。您是否尝试过 A*(假设您可以为您的图表找到启发式方法)?
-
在线评委评价此方案超过时限。我不知道如何进一步优化这个解决方案。我不认为 A* 会起作用,因为没有办法跟踪离目的地有多近(或者该图是否存在另一种启发式方法?)
-
可能想在这里发帖:stats.stackexchange.com
-
我不认为这是一个统计问题...
标签: python python-3.x graph-theory shortest-path dijkstra