예제 #1
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)
예제 #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 relaxed_plan(state, goal, operators, unit=False, greedy=True):
  variable_nodes = defaultdict(dict)
  operator_nodes = {}
  conditions = defaultdict(lambda: defaultdict(list))
  unsatisfied = {}
  queue = PriorityQueue()

  def union(nodes):
    operators = set(flatten(node.operators for node in nodes))
    cost = sum(operator.cost for operator in operators) if not unit else len(operators)
    return Node(cost, operators)

  def applicable_operator(operator):
    operator_nodes[operator] = union(variable_nodes[v][val] for v, val in operator.cond())
    if operator != goal:
      variable_node = union([operator_nodes[operator], Node(None, {operator})])
      for var2, value2 in operator.eff():
        if value2 not in variable_nodes[var2] or variable_node.cost < variable_nodes[var2][value2].cost:
          variable_nodes[var2][value2] = variable_node
          queue.push(variable_node.cost, (var2, value2))

  for operator in operators + [goal]:
    unsatisfied[operator] = len(operator.conditions)
    for var, value in operator.cond(): # TODO - store this in memory
      conditions[var][value].append(operator)
    if unsatisfied[operator] == 0:
      applicable_operator(operator)
      if greedy and operator == goal:
        return operator_nodes, variable_nodes
  for var in conditions:
    for value in conditions[var]:
      if state[var] == value:
        variable_nodes[var][value] = Node(0, {})
        queue.push(variable_nodes[var][value].cost, (var, value))

  processed = defaultdict(set)
  while not queue.empty():
    var, value = queue.pop()
    if value in processed[var]: continue
    processed[var].add(value)

    for operator in conditions[var][value]:
      unsatisfied[operator] -= 1
      if unsatisfied[operator] == 0:
        applicable_operator(operator)
        if greedy and operator == goal:
          return operator_nodes, variable_nodes
  return operator_nodes, variable_nodes
예제 #4
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)
예제 #5
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)
예제 #6
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
예제 #7
0
 def test_empty_queue(self):
     """test operations on an empty queue"""
     queue = PriorityQueue()
     self.assertEqual(len(queue), 0)
     self.assertRaises(IndexError, queue.popleft)