예제 #1
0
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
예제 #2
0
 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)
예제 #3
0
    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)
예제 #4
0
 def test_empty_queue(self):
     """test operations on an empty queue"""
     queue = PriorityQueue()
     self.assertEqual(len(queue), 0)
     self.assertRaises(IndexError, queue.popleft)