Пример #1
0
 def find_shortest_path(cls, net, depart_time, start, end=None):
     if end != None and start == end:
         return {end.id: (None, 0.0, depart_time)}
     # creater a FIFO queue for searching
     queue = deque()
     # create containers with default values
     cost = defaultdict(constant_factory(float('+inf')))
     time = defaultdict(constant_factory(float('+inf')))
     prev = defaultdict(None)
     # set values for the start node
     cost[start.id] = 0.0
     time[start.id] = depart_time
     queue.appendleft(start.id)
     # continue until the queue is empty
     while len(queue) > 0:
         # pop out the first object in the queue
         qtop = queue.pop()
         node = net.nodes[qtop]
         # relax each adjacent edges
         for edge in node.adj_edges:
             # get the traffic flow on the edge
             if Time.lessthan_maxtick(time[node.id]):
                 edge_flow = net.flows[edge.id][time[node.id]]
             else:
                 edge_flow = 0.0
             # if the relaxation makes a shorter path
             travel_time = edge.calc_travel_time(edge_flow)
             travel_cost = edge.calc_travel_cost(travel_time)
             if cost[edge.tail.id] > cost[node.id] + travel_cost:
                 # then update cost and time labels
                 cost[edge.tail.id] = cost[node.id] + travel_cost
                 time[edge.tail.id] = time[node.id] + travel_time
                 # and save the edge on the shortest path
                 prev[edge.tail.id] = edge
                 # and append the expanded node to the queue
                 queue.appendleft(edge.tail.id)
     # if end node is given, extract the shortest path to end node recursively
     if end != None:
         # if the end node is reached, there is at least one path
         # if the end node is not reached, the start and end nodes are not connected
         path = cls.create_shortest_path(start, end, prev, time) if end.id in prev else None
         return {end.id: (path, cost[end.id], time[end.id])}
     else:
         # if end node is not given, extract the shortest paths from start to all the other nodes
         paths = cls.create_all_shortest_paths(start, prev, time)
         # no path is defined for a ring and the travel time/cost is zero
         tuples = {start.id: (None, 0.0, depart_time)}
         for id_ in paths:
             # wrap the path, cost and time in a tuple
             # note that time[id_] is the arrival time at node[id_]
             # that is, time[id_] = depart_time + travel_time
             tuples[id_] = (paths[id_], cost[id_], time[id_])
         return tuples