Illustrates the use of the PriorityQueue constructor and methods
What is the worst-case time complexity of these methods?
Creating and using a MaxHeap
# create a PriorityQueue instance where the# key is the opposite of the input value of xmaxheap = PriorityQueue(key =lambda x: -x)# does not specify a priority for a valuen =10for i inrange(n): maxheap.insert(i)# displays the values in decreasing orderprint([maxheap.removemin() for _ inrange(n)])
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Creates a PriorityQueue to store values in decreasing order
Conveniently coalesces the key and the value into a single key
Note that the removemin function was not changed in any way!
Performing a HeapSort
def heapsort(L): H = PriorityQueue(L) L[:] = [item for item in H]L = [3, 2, 4, 1, 6, 5]print("Before heapsort:", L)heapsort(L)print("After heapsort: ", L)
Before heapsort: [3, 2, 4, 1, 6, 5]
After heapsort: [1, 2, 3, 4, 5, 6]
Uses the _heapify method to create a PriorityQueue in \(O(n)\)
Iteration over each item in list comprehension costs \(O(\log n)\)
This means that the heapsort function has a time complexity of \(O(n \log
n)\). Is this better, worse, or the same as mergesort?
Define a Job class with name, priority, and duration
Create three Job instances with different priorities and durations
Running Jobs with a PriorityQueue
# run all of the jobs in order of prioritywhilenotlen(job_queue) ==0: next_job = job_queue.removemin()print(f"Running {next_job}")for i inrange(next_job.duration):print(f"{next_job.name} is running...")print(f"{next_job.name} has finished running.")
Running Job: Medium-running job 2, Priority: 1, Duration: 2
Medium-running job 2 is running...
Medium-running job 2 is running...
Medium-running job 2 has finished running.
Running Job: Short-running job 3, Priority: 2, Duration: 1
Short-running job 3 is running...
Short-running job 3 has finished running.
Running Job: Long-running job 1, Priority: 3, Duration: 5
Long-running job 1 is running...
Long-running job 1 is running...
Long-running job 1 is running...
Long-running job 1 is running...
Long-running job 1 is running...
Long-running job 1 has finished running.
Try the PriorityQueue of Jobs
Job scheduling with PriorityQueue
Job representation
Leverages Entry, HeapPQ, and PriorityQueue classes
Job class with name, priority, and duration attributes
Lower priority values indicate higher importance
Scheduling process
Jobs stored in a PriorityQueue ordered by priority
removemin() selects the next highest-priority job
Each job runs for its full duration before next job starts
What are the limitations of this job scheduler? Why?
Process scheduling in the Linux kernel
Multi-level feedback queue
Dynamic priority adjustment based on behavior
I/O-bound processes get priority boosts
CPU-bound processes get priority penalties
Preemption and timeslices
Processes run for short time quantum
Long-running processes don’t block others
Real-time processes have special scheduling classes