Python Dijkstra和#x27的卡蒂斯时限超过;一类最短路径问题的s算法

Python Dijkstra和#x27的卡蒂斯时限超过;一类最短路径问题的s算法,python,algorithm,performance,time,shortest-path,Python,Algorithm,Performance,Time,Shortest Path,我目前正在尝试解决:这是一个具有正权重的最短路径问题,我对Python非常陌生 我已经实现了算法和主要功能。对于他们的第一个测试用例,它可以正常工作,但是对于第二个测试用例,它超过了>3s的时间限制,导致我的代码没有被接受为答案,我相信我的代码中有一个错误(并且不是真正的优化错误,因为我相信3秒应该足够时间) 我能做些什么来改进我的代码,使其通过第二个测试用例 from collections import deque, namedtuple inf = float('inf') Edge =

我目前正在尝试解决:这是一个具有正权重的最短路径问题,我对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")
从集合导入deque,命名为tuple
inf=浮点('inf')
Edge=namedtuple('Edge','start,end,cost'))
def make_edge(开始、结束、成本=1):
返回边缘(开始、结束、成本)
类图:
定义初始(自,边):
self.edges=[make_edge(*edge)表示边中的边]
@财产
定义顶点(自身):
返回集(
总数(
([edge.start,edge.end]用于self.edge中的edge),[]
)
)
def get_node_对(self、n1、n2,两端=True):
如果两者都结束:
节点对=[[n1,n2],[n2,n1]]
其他:
节点对=[[n1,n2]]
返回节点对
def移除_边缘(自身、n1、n2、两端=真):
节点对=自身。获取节点对(n1,n2,两端)
边=自身。边[:]
对于边中的边:
如果节点对中的[edge.start,edge.end]:
自。边。删除(边)
def add_edge(自身、n1、n2、成本=1、两端=真):
节点对=自身。获取节点对(n1,n2,两端)
#对于self.edges中的边:
#如果节点对中的[edge.start,edge.end]:
#返回值错误('边{}{}已经存在'。格式(n1,n2))
self.edges.append(边缘(开始=n1,结束=n2,成本=cost))
如果两者都结束:
self.edges.append(Edge(开始=n2,结束=n1,成本=cost))
@财产
def邻居(自我):
邻居={vertex:set()表示self.vertexs}中的顶点
对于self.edges中的边:
邻居[edge.start]。添加((edge.end,edge.cost))
回乡
def dijkstra(自身、源、目标):
#在self.vertices中断言源,“此类源节点不存在”
距离={vertex:inf表示self.vertexs}中的顶点
以前的_顶点={
顶点:self.vertexs中的顶点无
}
距离[源]=0
顶点=self.vertices.copy()
而顶点:
当前顶点=最小值(
顶点,关键点=λ顶点:距离[顶点])
顶点。删除(当前顶点)
如果距离[当前顶点]==inf:
打破
对于邻居,以自身为单位计算成本。邻居[当前顶点]:
备选路径=距离[当前顶点]+成本
如果备选路线<距离[邻居]:
距离[邻居]=备选路线
上一个\u顶点[邻居]=当前\u顶点
#Deque er som list men med O(1)超过O(N)以获得list.pop()
路径,当前顶点=deque(),dest
虽然以前的_顶点[当前_顶点]不是无:
path.appendleft(当前_顶点)
当前顶点=上一个顶点[当前顶点]
如果路径:
path.appendleft(当前_顶点)
#在此处返回path以获取deque,path为字符串列表
#需要距离:
d=0
对于范围(len(path))中的索引:
对于自边中的x:
如果x.start==路径[index-1]和x.end==路径[index]:
d+=x.成本
返回d
如果名称=“\uuuuu main\uuuuuuuu”:
#边1=边(“0”、“1”、2)
#边2=边(“1”、“2”、2)
#testGraph2()
#同时检测får输入。。
n、 m,q,s=[0,0,0,0]
u、 v,w=[0,0,0]
尽管如此:
边=[]
[n,m,q,s]=input().split()
#打印(“n:,n,“m:,m”,“q”,“q”,“s:,s”)
如果n==“0”和m==“0”和q==“0”和s==“0”:
打破
对于范围内的i(int(m)):
[u,v,w]=input().split()
追加(边(u,v,int(w)))
图形=图形(边)
对于范围内的j(int(q)):
q=输入()
距离=图形dijkstra(s,q)
如果距离==0和s!=问:
打印(“不可能”)
其他:
打印(距离)
打印(“\n”)

对于每个查询,您都在重新计算djikstra,这可能是重复的。