我目前正在尝试解决:https://open.kattis.com/problems/shortestpath1,这是权重为正的最短路径问题,对Python来说我还很陌生。
我已经实现了算法和主要功能。对于第一个测试用例,它可以正常工作,但对于第二个用例,则超过了> 3s的时间限制,导致我的代码没有被接受为答案,而且我认为我的代码中有错误(并且实际上不是优化)错误,因为我认为3秒钟应该就足够了。
该如何改进我的代码,使其通过第二个测试用例?
from collections import deque, namedtuple
inf = float('inf')
Edge = namedtuple('Edge', 'start, end, cost')
def make_edge(start, end, cost=1):
return Edge(start, end, cost)
class Graph:
def __init__(self, edges):
self.edges = [make_edge(*edge) for edge in edges]
@property
def vertices(self):
return set(
sum(
([edge.start, edge.end] for edge in self.edges), []
)
)
def get_node_pairs(self, n1, n2, both_ends=True):
if both_ends:
node_pairs = [[n1, n2], [n2, n1]]
else:
node_pairs = [[n1, n2]]
return node_pairs
def remove_edge(self, n1, n2, both_ends=True):
node_pairs = self.get_node_pairs(n1, n2, both_ends)
edges = self.edges[:]
for edge in edges:
if [edge.start, edge.end] in node_pairs:
self.edges.remove(edge)
def add_edge(self, n1, n2, cost=1, both_ends=True):
node_pairs = self.get_node_pairs(n1, n2, both_ends)
#for edge in self.edges:
#if [edge.start, edge.end] in node_pairs:
#return ValueError('Edge {} {} already exists'.format(n1, n2))
self.edges.append(Edge(start=n1, end=n2, cost=cost))
if both_ends:
self.edges.append(Edge(start=n2, end=n1, cost=cost))
@property
def neighbours(self):
neighbours = {vertex: set() for vertex in self.vertices}
for edge in self.edges:
neighbours[edge.start].add((edge.end, edge.cost))
return neighbours
def dijkstra(self, source, dest):
#assert source in self.vertices, 'Such source node doesn\'t exist'
distances = {vertex: inf for vertex in self.vertices}
previous_vertices = {
vertex: None for vertex in self.vertices
}
distances[source] = 0
vertices = self.vertices.copy()
while vertices:
current_vertex = min(
vertices, key=lambda vertex: distances[vertex])
vertices.remove(current_vertex)
if distances[current_vertex] == inf:
break
for neighbour, cost in self.neighbours[current_vertex]:
alternative_route = distances[current_vertex] + cost
if alternative_route < distances[neighbour]:
distances[neighbour] = alternative_route
previous_vertices[neighbour] = current_vertex
#Deque er som list men med O(1) over O(N) for list.pop()
path, current_vertex = deque(), dest
while previous_vertices[current_vertex] is not None:
path.appendleft(current_vertex)
current_vertex = previous_vertices[current_vertex]
if path:
path.appendleft(current_vertex)
#return path here to get the deque with path as list of strings
#need the distance:
d = 0
for index in range(len(path)):
for x in self.edges:
if x.start == path[index-1] and x.end == path[index]:
d += x.cost
return d
if __name__ == "__main__":
#edge1 = Edge("0", "1", 2)
#edge2 = Edge("1", "2", 2)
#testGraph2()
#while dette får input..
n, m, q, s = [0, 0, 0, 0]
u, v, w = [0, 0, 0]
while True:
edges = []
[n, m, q, s] = input().split()
#print("n: ", n, "m: ", m, "q", q, "s: ", s)
if n == "0" and m == "0" and q == "0" and s == "0":
break
for i in range(int(m)):
[u, v, w] = input().split()
edges.append(Edge(u, v, int(w)))
graph = Graph(edges)
for j in range(int(q)):
q = input()
distance = graph.dijkstra(s, q)
if distance == 0 and s != q:
print("Impossible")
else:
print(distance)
print("\n")