0

How do I insert items into a priority queue, but ensure that it only takes as it's priority the first argument given. For example:

    #push up
    if((pacman_r != 0 ) and (cellGrid[pacman_r-1][pacman_c].what != '%')):
        priorityQueue.put((4, pacman_r-1, pacman_c))
    #push left 
    if ((pacman_c != 0) and (cellGrid[pacman_r][pacman_c-1].what != '%')):
        priorityQueue.put((4, pacman_r, pacman_c-1))
    #push right
    if ((pacman_c != c) and (cellGrid[pacman_r][pacman_c+1].what != '%')):
        priorityQueue.put((9, pacman_r, pacman_c+1))
    #push down
    if((pacman_r != r ) and (cellGrid[pacman_r+1][pacman_c].what != '%')):
        priorityQueue.put((1, pacman_r+1, pacman_c))

I would like the top two if statements to be placed into priorityQueue LIFO. How would I do this?

tshepang
  • 12,111
  • 21
  • 91
  • 136
David
  • 1,398
  • 1
  • 14
  • 20

2 Answers2

1

Pass the arguments as a separate tuple:

 priorityQueue.put( (4, (pacman_r-1, pacman_c)) )
perreal
  • 94,503
  • 21
  • 155
  • 181
  • I tried this out but it just seems to use the second tuple as the priority key, using the values of the string... Can I make it ignore the second tuple? – David May 16 '14 at 04:10
  • Then change the order: `priorityQueue.put( ((pacman_r-1, pacman_c), 4) )` – perreal May 16 '14 at 04:12
  • It then uses the "(pacman_r-1, pacman_c)" string as the priority key. – David May 16 '14 at 04:25
0

If you want equal priority elements to be returned in a LIFO order, you should add a count value to your keys:

# put this with your other import statements
from itertools import count

# put this near where you define your priority queue
counter = count()

#later, add the counter's latest value as a second key value:
#push up
if((pacman_r != 0 ) and (cellGrid[pacman_r-1][pacman_c].what != '%')):
    priorityQueue.put((4, -next(counter), pacman_r-1, pacman_c))
#push left 
if ((pacman_c != 0) and (cellGrid[pacman_r][pacman_c-1].what != '%')):
    priorityQueue.put((4, -next(counter), pacman_r, pacman_c-1))
#push right
if ((pacman_c != c) and (cellGrid[pacman_r][pacman_c+1].what != '%')):
    priorityQueue.put((9, -next(counter), pacman_r, pacman_c+1))
#push down
if((pacman_r != r ) and (cellGrid[pacman_r+1][pacman_c].what != '%')):
    priorityQueue.put((1, -next(counter), pacman_r+1, pacman_c))

This makes your values be four-tuples, rather than three-tuples (so you'll need to update the code you use to access the values). The second value will be steadily decreasing (count yields successively increasing integers forever, and we're negating them). If the first values of two tuples in the queue are equal, the second values will be compared and the most recently added one will always be the smallest (and so selected by the queue).

By the way, unless you're using your queue to synchronize data between multiple threads, you should probably be using the heapq module's functions on a regular list, rather than using a queue.PriorityQueue instance. The latter uses heapq to implement its logic internally, but it also does a bunch of locking that you probably don't need (for single threaded code it is pointless overhead).

Blckknght
  • 100,903
  • 11
  • 120
  • 169