def dijkstra(G, r): if not G.has_node(r):#if the graph doesnt have this node raise ValueError("Source node " + str(r) + " not present") for e1, e2, d in G.edges(data=True):#cant handle negitive weights if d["weight"] < 0: raise ValueError("Negative weight on edge " + str(e1) + "-" + str(e2)) P = {r} # permanent set S = PriorityQueue() # V-P. This is the crucial data structure. D = {} # estimates of SPST lengths p = {} # parent-pointers A = set() # our result, an SPST for n in G.nodes():#for all nodes if n == r:#if we're at the source node... D[n] = 0#...its weight is zero else: if G.has_edge(r, n):#if we're at a neighbour D[n] = G[r][n]["weight"]#path is the weight of the edge else: D[n] = math.inf p[n] = r S.add_task(n, D[n]) while len(S): u, Du = S.pop_task() if u in P: continue P.add(u) # move one item to the permanent set P and to SPST A A.add((p[u], u)) for v, Dv in S: if v in P: continue if G.has_edge(u, v): if D[v] > D[u] + G[u][v]["weight"]: D[v] = D[u] + G[u][v]["weight"] p[v] = u S.add_task(v, D[v]) # add v, or update its prior results={} results["SPST"]=A #SPST results["predecessors"]=p #predecessors results["distances"]=D #distances sorted_D = sorted(D.items(), key=operator.itemgetter(1)) results["generator"]=(n for n in sorted_D) return results # let's return the SPST, predecessors and distances: user can decide which to use
def test_single_entry(self): """test adding and removing a single entry""" queue = PriorityQueue() message = message_format(ident=None, control={"priority": 0}, body=None) self.assertEqual(len(queue), 0) queue.append(( message.control, message.body, )) self.assertEqual(len(queue), 1) retrieved_message, _retrieved_body = queue.popleft() self.assertEqual(retrieved_message, message.control) self.assertEqual(len(queue), 0) self.assertRaises(IndexError, queue.popleft)
def test_message_order(self): """test that we get messages in the order we expect""" queue = PriorityQueue() messages = [ message_format(ident=None, control={ "priority": 0, "expected-order": 0 }, body=None), message_format(ident=None, control={ "priority": 5, "expected-order": 2 }, body=None), message_format(ident=None, control={ "priority": 3, "expected-order": 1 }, body=None), ] self.assertEqual(len(queue), 0) for message in messages: queue.append(( message.control, message.body, )) self.assertEqual(len(queue), len(messages)) for order in range(len(messages)): retrieved_message, _retrieved_data = queue.popleft() self.assertEqual(order, retrieved_message["expected-order"]) self.assertEqual(len(queue), 0) self.assertRaises(IndexError, queue.popleft)
def test_empty_queue(self): """test operations on an empty queue""" queue = PriorityQueue() self.assertEqual(len(queue), 0) self.assertRaises(IndexError, queue.popleft)