Open In App

Heap and Priority Queue using heapq module in Python

Heaps are widely used tree-like data structures in which the parent nodes satisfy any one of the criteria given below.

The heaps are complete binary trees and are used in the implementation of the priority queues. The min-heaps play a vital role in scheduling jobs, scheduling emails or in assigning the resources to tasks based on the priority. 



Priority queues

These are abstract data types and are a special form of queues. The elements in the queue have priorities assigned to them. Based on the priorities, the first element in the priority queue will be the one with the highest priority. The basic operations associated with these priority queues are listed below: 

The priority queues can be used for all scheduling kind of processes. The programmer can decide whether the largest number is considered as the highest priority or the lowest number will be considered as the highest priority. If two elements have the same priority, then they appear in the order in which they appear in the queue. 



heapq module in Python

Heapq module is an implementation of heap queue algorithm (priority queue algorithm) in which the property of min-heap is preserved. The module takes up a list of items and rearranges it such that they satisfy the following criteria of min-heap:

Priority queues using heapq module

The priority queue is implemented in Python as a list of tuples where the tuple contains the priority as the first element and the value as the next element.

Example : [ (1, 2), (2, 3), (4, 5), (6,7)]

consider (1,2) : 

  • Priority : 1
  • Value/element : 2

Example:

Consider a simple priority queue implementation for scheduling the presentations of students based on their roll number. Here roll number decides the priority of the student to present. Since it is a min-heap, roll number 1 is considered to be of the highest priority.




# import modules
import heapq as hq
  
# list of students
list_stu = [(5,'Rina'),(1,'Anish'),(3,'Moana'),(2,'cathy'),(4,'Lucy')]
  
# Arrange based on the roll number
hq.heapify(list_stu)
  
print("The order of presentation is :")
  
for i in list_stu:
  print(i[0],':',i[1])

Output
The order of presentation is :
1 : Anish
2 : cathy
3 : Moana
5 : Rina
4 : Lucy

Example 2:

Now let us implement a simple scheduler that assigns the jobs to the processor. The priority queue is used by the scheduler to decide which task has to be performed. Apart from the tasks, there will be interrupts approaching the scheduler. So the scheduler has to decide whether to execute the interrupt or the existing task. If the interrupt has a higher priority, it is executed first otherwise, once all the jobs are completed, the interrupt will be serviced. To implement this the heapq module is used. The approach is given below.




import time
import heapq as hq
  
# jobs to be executed
jobs = [(2, 'task_1'), (5, 'task_2'), (1, 'task_4'),
        (4, 'task_5'), (3, 'task_3'), (1, 'task_8')]
  
# interrupts
interrupts = [(1, 'intr_1'), (2, 'intr_2'), (13, 'intr_3')]
  
i, j = 0, 0
  
# Arranging jobs in heap
hq.heapify(jobs)
  
print(jobs, "\n\n")
  
# scheduling the tasks
while len(jobs) != 0:
  
    # printing execution log
    print("The ", jobs[0][1], " with priority ",
          jobs[0][0], " in progress", end="")
  
    # servicing the tasks
    for _ in range(0, 5):
  
        print(".", end="")
        time.sleep(0.5)
  
    # pop the job that completed
    hq.heappop(jobs)
  
    # adding interrupts
    if j < len(interrupts):
  
        hq.heappush(jobs, interrupts[j])
        print("\n\nNew interrupt arrived!!", interrupts[j])
        print()
        j = j+1
  
    # job queue after arrival of interrupt
    print("\n Job queue currently :", jobs)
    print("\n")
  
  
print("\nAll interrupts and jobs completed!")

Output


Article Tags :