Program for HRRN CPU Scheduling Algorithm
Last Updated :
10 Jan, 2025
The Highest Response Ratio Next (HRRN) scheduling algorithm is a non-preemptive scheduling technique used in operating systems to manage the execution of processes. It is designed to improve upon simpler algorithms like First-Come-First-Serve (FCFS) and Shortest Job Next (SJN) by balancing both the waiting time and the burst time of processes.
The key idea behind HRRN is to calculate a response ratio for each process, which is a measure of how long a process has been waiting compared to the time it needs for execution. The formula for the response ratio is:
In HRRN, the process with the highest response ratio is selected for execution next. This approach gives priority to processes that have been waiting longer, but also considers the burst time, ensuring a fair balance between long-waiting and quick-execution processes.
HRRN aims to reduce both starvation (by giving priority to long-waiting processes) and the inefficiency of short-job priority (by balancing burst time with waiting time). It provides a more efficient and fair way of scheduling processes, making it suitable for systems where long and short tasks need to be managed together.
Implementation of HRRN Scheduling
- Input the number of processes, their arrival times and burst times.
- Sort them according to their arrival times.
- At any given time calculate the response ratios and select the appropriate process to be scheduled.
- Calculate the turn around time as completion time - arrival time.
- Calculate the waiting time as turn around time - burst time.
- Turn around time divided by the burst time gives the normalized turn around time.
- Sum up the waiting and turn around times of all processes and divide by the number of processes to get the average waiting and turn around time.
Below is the implementation of above approach:
C++
// C++ program for Highest Response Ratio Next (HRRN)
// Scheduling
#include <bits/stdc++.h>
using namespace std;
// Defining process details
struct process
{
char name;
int at, bt, ct, wt, tt;
int completed;
float ntt;
} p[10];
int n;
// Sorting Processes by Arrival Time
void sortByArrival()
{
struct process temp;
int i, j;
// Selection Sort applied
for (i = 0; i < n - 1; i++)
{
for (j = i + 1; j < n; j++)
{
// Check for lesser arrival time
if (p[i].at > p[j].at)
{
// Swap earlier process to front
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
}
int main()
{
int i, j, sum_bt = 0;
char c;
float t, avgwt = 0, avgtt = 0;
n = 5;
// predefined arrival times
int arriv[] = {0, 2, 4, 6, 8};
// predefined burst times
int burst[] = {3, 6, 4, 5, 2};
// Initializing the structure variables
for (i = 0, c = 'A'; i < n; i++, c++)
{
p[i].name = c;
p[i].at = arriv[i];
p[i].bt = burst[i];
// Variable for Completion status
// Pending = 0
// Completed = 1
p[i].completed = 0;
// Variable for sum of all Burst Times
sum_bt += p[i].bt;
}
// Sorting the structure by arrival times
sortByArrival();
cout << "PN\tAT\tBT\tWT\tTAT\tNTT";
for (t = p[0].at; t < sum_bt;)
{
// Set lower limit to response ratio
float hrr = -9999;
// Response Ratio Variable
float temp;
// Variable to store next process selected
int loc;
for (i = 0; i < n; i++)
{
// Checking if process has arrived and is
// Incomplete
if (p[i].at <= t && p[i].completed != 1)
{
// Calculating Response Ratio
temp = (p[i].bt + (t - p[i].at)) / p[i].bt;
// Checking for Highest Response Ratio
if (hrr < temp)
{
// Storing Response Ratio
hrr = temp;
// Storing Location
loc = i;
}
}
}
// Updating time value
t += p[loc].bt;
// Calculation of waiting time
p[loc].wt = t - p[loc].at - p[loc].bt;
// Calculation of Turn Around Time
p[loc].tt = t - p[loc].at;
// Sum Turn Around Time for average
avgtt += p[loc].tt;
// Calculation of Normalized Turn Around Time
p[loc].ntt = ((float)p[loc].tt / p[loc].bt);
// Updating Completion Status
p[loc].completed = 1;
// Sum Waiting Time for average
avgwt += p[loc].wt;
cout << "\n" << p[loc].name << "\t" << p[loc].at;
cout << "\t" << p[loc].bt << "\t" << p[loc].wt;
cout << "\t" << p[loc].tt << "\t" << p[loc].ntt;
}
cout << "\nAverage waiting time: " << avgwt / n << endl;
cout << "Average Turn Around time:" << avgtt / n;
}
C
// C program for Highest Response Ratio Next (HRRN) Scheduling
#include <stdio.h>
// Defining process details
struct process {
char name;
int at, bt, ct, wt, tt;
int completed;
float ntt;
} p[10];
int n;
// Sorting Processes by Arrival Time
void sortByArrival()
{
struct process temp;
int i, j;
// Selection Sort applied
for (i = 0; i < n - 1; i++) {
for (j = i + 1; j < n; j++) {
// Check for lesser arrival time
if (p[i].at > p[j].at) {
// Swap earlier process to front
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
}
void main()
{
int i, j, t, sum_bt = 0;
char c;
float avgwt = 0, avgtt = 0;
n = 5;
// predefined arrival times
int arriv[] = { 0, 2, 4, 6, 8 };
// predefined burst times
int burst[] = { 3, 6, 4, 5, 2 };
// Initializing the structure variables
for (i = 0, c = 'A'; i < n; i++, c++) {
p[i].name = c;
p[i].at = arriv[i];
p[i].bt = burst[i];
// Variable for Completion status
// Pending = 0
// Completed = 1
p[i].completed = 0;
// Variable for sum of all Burst Times
sum_bt += p[i].bt;
}
// Sorting the structure by arrival times
sortByArrival();
printf("\nName\tArrival Time\tBurst Time\tWaiting Time");
printf("\tTurnAround Time\t Normalized TT");
for (t = p[0].at; t < sum_bt;) {
// Set lower limit to response ratio
float hrr = -9999;
// Response Ratio Variable
float temp;
// Variable to store next process selected
int loc;
for (i = 0; i < n; i++) {
// Checking if process has arrived and is Incomplete
if (p[i].at <= t && p[i].completed != 1) {
// Calculating Response Ratio
temp = (p[i].bt + (t - p[i].at)) / p[i].bt;
// Checking for Highest Response Ratio
if (hrr < temp) {
// Storing Response Ratio
hrr = temp;
// Storing Location
loc = i;
}
}
}
// Updating time value
t += p[loc].bt;
// Calculation of waiting time
p[loc].wt = t - p[loc].at - p[loc].bt;
// Calculation of Turn Around Time
p[loc].tt = t - p[loc].at;
// Sum Turn Around Time for average
avgtt += p[loc].tt;
// Calculation of Normalized Turn Around Time
p[loc].ntt = ((float)p[loc].tt / p[loc].bt);
// Updating Completion Status
p[loc].completed = 1;
// Sum Waiting Time for average
avgwt += p[loc].wt;
printf("\n%c\t\t%d\t\t", p[loc].name, p[loc].at);
printf("%d\t\t%d\t\t", p[loc].bt, p[loc].wt);
printf("%d\t\t%f", p[loc].tt, p[loc].ntt);
}
printf("\nAverage waiting time:%f\n", avgwt / n);
printf("Average Turn Around time:%f\n", avgtt / n);
}
Java
// Java equivalent
import java.util.Arrays;
// Defining process details
class Process {
char name;
int at, bt, ct, wt, tt;
int completed;
float ntt;
}
public class HRRN {
// Sorting Processes by Arrival Time
static void sortByArrival(Process p[], int n)
{
Process temp;
int i, j;
// Selection Sort applied
for (i = 0; i < n - 1; i++) {
for (j = i + 1; j < n; j++) {
// Check for lesser arrival time
if (p[i].at > p[j].at) {
// Swap earlier process to front
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
}
public static void main(String[] args)
{
int i, j, sum_bt = 0;
char c;
float t, avgwt = 0, avgtt = 0;
int n = 5;
// predefined arrival times
int arriv[] = { 0, 2, 4, 6, 8 };
// predefined burst times
int burst[] = { 3, 6, 4, 5, 2 };
Process[] p = new Process[n];
// Initializing the structure variables
for (i = 0, c = 'A'; i < n; i++, c++) {
p[i] = new Process();
p[i].name = c;
p[i].at = arriv[i];
p[i].bt = burst[i];
// Variable for Completion status
// Pending = 0
// Completed = 1
p[i].completed = 0;
// Variable for sum of all Burst Times
sum_bt += p[i].bt;
}
// Sorting the structure by arrival times
sortByArrival(p, n);
System.out.println("PN\tAT\tBT\tWT\tTAT\tNTT");
for (t = p[0].at; t < sum_bt;) {
// Set lower limit to response ratio
float hrr = -9999;
// Response Ratio Variable
float temp;
// Variable to store next process selected
int loc = -1;
for (i = 0; i < n; i++) {
// Checking if process has arrived and is
// Incomplete
if (p[i].at <= t && p[i].completed != 1) {
// Calculating Response Ratio
temp = (p[i].bt + (t - p[i].at)) / p[i].bt;
// Checking for Highest Response Ratio
if (hrr < temp) {
// Storing Response Ratio
hrr = temp;
// Storing Location
loc = i;
}
}
}
// Updating time value
t += p[loc].bt;
// Calculation of waiting time
p[loc].wt = (int)(t - p[loc].at - p[loc].bt);
// Calculation of Turn Around Time
p[loc].tt = (int)(t - p[loc].at);
// Sum Turn Around Time for average
avgtt += p[loc].tt;
// Calculation of Normalized Turn Around Time
p[loc].ntt = ((float)p[loc].tt / p[loc].bt);
// Updating Completion Status
p[loc].completed = 1;
// Sum Waiting Time for average
avgwt += p[loc].wt;
System.out.println(p[loc].name + "\t" + p[loc].at + "\t" + p[loc].bt
+ "\t" + p[loc].wt + "\t" + p[loc].tt
+ "\t" + p[loc].ntt);
}
System.out.println("Average waiting time: " + (avgwt / n));
System.out.println("Average Turn Around time:" + (avgtt / n));
}
}
Python
# Python3 program for Highest Response Ratio
# Next (HRRN) Scheduling
# Function to sort process by arrival time
def sortByArrival(at, n):
# Selection Sort applied
for i in range(0, n - 1):
for j in range(i + 1, n):
# Check for lesser arrival time
if at[i] > at[j]:
# Swap earlier process to front
at[i], at[j] = at[j], at[i]
# Driver code
if __name__ == '__main__':
sum_bt = 0
avgwt = 0
avgTT = 0
n = 5
completed =[0] * n
waiting_time = [0] * n
turnaround_time = [0] * n
normalised_TT = [0] * n
# Predefined arrival times
arrival_time = [ 0, 2, 4, 6, 8 ]
# Predefined burst times
burst_time = [ 3, 6, 4, 5, 2 ]
process = []
# Initializing the structure variables
for i in range(0, n):
process.append(chr(65 + i))
sum_bt += burst_time[i]
# Sorting the structure by arrival times
sortByArrival(arrival_time, n)
print("Name", "Arrival time",
"Burst time", "Waiting Time",
"Turnaround ", "Normalized TT")
t = arrival_time[0]
while(t < sum_bt):
# Set lower limit to response ratio
hrr = -9999
temp, loc = 0, 0
for i in range(0, n):
# Checking if process has arrived
# and is Incomplete
if arrival_time[i] <= t and completed[i] != 1:
# Calculating Response Ratio
temp = ((burst_time[i] +
(t - arrival_time[i])) /
burst_time[i])
# Checking for Highest Response Ratio
if hrr < temp:
# Storing Response Ratio
hrr = temp
# Storing Location
loc = i
# Updating time value
t += burst_time[loc]
# Calculation of waiting time
waiting_time[loc] = (t - arrival_time[loc] -
burst_time[loc])
# Calculation of Turn Around Time
turnaround_time[loc] = t - arrival_time[loc]
# Sum Turn Around Time for average
avgTT += turnaround_time[loc]
# Calculation of Normalized Turn Around Time
normalised_TT = float(turnaround_time[loc] /
burst_time[loc])
# Updating Completion Status
completed[loc] = 1
# Sum Waiting Time for average
avgwt += waiting_time[loc]
print(process[loc], "\t\t", arrival_time[loc],
"\t\t", burst_time[loc], "\t\t",
waiting_time[loc], "\t\t",
turnaround_time[loc], "\t\t",
"{0:.6f}".format(normalised_TT))
print("Average waiting time: {0:.6f}".format(avgwt / n))
print("Average Turn Around time: {0:.6f}".format(avgTT / n))
# This code is contributed by etcharla revanth rao
C#
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
// C# equivalent
// Defining process details
class Process {
public char name;
public int at, bt, ct, wt, tt;
public int completed;
public float ntt;
}
class HelloWorld {
// Sorting Processes by Arrival Time
public static void sortByArrival(Process[] p, int n)
{
Process temp;
int i, j;
// Selection Sort applied
for (i = 0; i < n - 1; i++) {
for (j = i + 1; j < n; j++) {
// Check for lesser arrival time
if (p[i].at > p[j].at) {
// Swap earlier process to front
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
}
static void Main()
{
int i, j, sum_bt = 0;
char c;
float t, avgwt = 0, avgtt = 0;
int n = 5;
// predefined arrival times
int[] arriv = { 0, 2, 4, 6, 8 };
// predefined burst times
int[] burst = { 3, 6, 4, 5, 2 };
Process[] p = new Process[n];
// Initializing the structure variables
for (i = 0, c = 'A'; i < n; i++, c++) {
p[i] = new Process();
p[i].name = c;
p[i].at = arriv[i];
p[i].bt = burst[i];
// Variable for Completion status
// Pending = 0
// Completed = 1
p[i].completed = 0;
// Variable for sum of all Burst Times
sum_bt += p[i].bt;
}
// Sorting the structure by arrival times
sortByArrival(p, n);
Console.WriteLine("PN\tAT\tBT\tWT\tTAT\tNTT");
for (t = p[0].at; t < sum_bt;) {
// Set lower limit to response ratio
float hrr = -9999;
// Response Ratio Variable
float temp;
// Variable to store next process selected
int loc = -1;
for (i = 0; i < n; i++) {
// Checking if process has arrived and is
// Incomplete
if (p[i].at <= t && p[i].completed != 1) {
// Calculating Response Ratio
temp = (p[i].bt + (t - p[i].at))
/ p[i].bt;
// Checking for Highest Response Ratio
if (hrr < temp) {
// Storing Response Ratio
hrr = temp;
// Storing Location
loc = i;
}
}
}
// Updating time value
t += p[loc].bt;
// Calculation of waiting time
p[loc].wt = (int)(t - p[loc].at - p[loc].bt);
// Calculation of Turn Around Time
p[loc].tt = (int)(t - p[loc].at);
// Sum Turn Around Time for average
avgtt += p[loc].tt;
// Calculation of Normalized Turn Around Time
p[loc].ntt = ((float)p[loc].tt / p[loc].bt);
// Updating Completion Status
p[loc].completed = 1;
// Sum Waiting Time for average
avgwt += p[loc].wt;
Console.WriteLine(p[loc].name + "\t" + p[loc].at
+ "\t" + p[loc].bt + "\t"
+ p[loc].wt + "\t" + p[loc].tt
+ "\t" + p[loc].ntt);
}
Console.WriteLine("Average waiting time: "
+ (avgwt / n));
Console.WriteLine("Average Turn Around time:"
+ (avgtt / n));
}
}
// The code is contributed by Nidhi goel.
JavaScript
// javascript program for Highest Response Ratio Next (HRRN)
// Scheduling
// Defining process details
class process {
constructor()
{
this.name = "#";
this.at = 0;
this.bt = 0;
this.ct = 0;
this.wt = 0;
this.tt = 0;
this.completed = 0;
this.ntt = 0;
}
}
let p = new Array(10);
for (let i = 0; i < 10; i++) {
p[i] = new process();
}
let n;
// Sorting Processes by Arrival Time
function sortByArrival()
{
let temp;
let i, j;
// Selection Sort applied
for (i = 0; i < n - 1; i++) {
for (j = i + 1; j < n; j++) {
// Check for lesser arrival time
if (p[i].at > p[j].at) {
// Swap earlier process to front
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
}
let i, j, sum_bt = 0;
let c;
let t, avgwt = 0, avgtt = 0;
n = 5;
// predefined arrival times
let arriv = [ 0, 2, 4, 6, 8 ];
// predefined burst times
let burst = [ 3, 6, 4, 5, 2 ];
// Initializing the structure variables
for (i = 0, c = "A"; i < n; i++) {
p[i].name = c;
p[i].at = arriv[i];
p[i].bt = burst[i];
// Variable for Completion status
// Pending = 0
// Completed = 1
p[i].completed = 0;
// Variable for sum of all Burst Times
sum_bt += p[i].bt;
c = String.fromCharCode(c.charCodeAt(0) + 1);
}
// Sorting the structure by arrival times
sortByArrival();
console.log("PN\tAT\tBT\tWT\tTAT\tNTT");
for (t = p[0].at; t < sum_bt;) {
// Set lower limit to response ratio
let hrr = -9999;
// Response Ratio Variable
let temp;
// Variable to store next process selected
let loc;
for (i = 0; i < n; i++) {
// Checking if process has arrived and is
// Incomplete
if (p[i].at <= t && p[i].completed != 1) {
// Calculating Response Ratio
temp = (p[i].bt + (t - p[i].at)) / p[i].bt;
// Checking for Highest Response Ratio
if (hrr < temp) {
// Storing Response Ratio
hrr = temp;
// Storing Location
loc = i;
}
}
}
// Updating time value
t += p[loc].bt;
// Calculation of waiting time
p[loc].wt = t - p[loc].at - p[loc].bt;
// Calculation of Turn Around Time
p[loc].tt = t - p[loc].at;
// Sum Turn Around Time for average
avgtt += p[loc].tt;
// Calculation of Normalized Turn Around Time
p[loc].ntt = (p[loc].tt / p[loc].bt);
// Updating Completion Status
p[loc].completed = 1;
// Sum Waiting Time for average
avgwt += p[loc].wt;
console.log(p[loc].name + "\t" + p[loc].at + "\t"
+ p[loc].bt + "\t" + p[loc].wt + "\t"
+ p[loc].tt + "\t" + p[loc].ntt);
}
console.log("\nAverage waiting time: " + avgwt / n);
console.log("Average Turn Around time:" + avgtt / n);
// This code is contributed by Nidhi goel.
Output:
PN AT BT WT TAT NTT
A 0 3 0 3 1
B 2 6 1 7 1.16667
C 4 4 5 9 2.25
E 8 2 5 7 3.5
D 6 5 9 14 2.8
Average waiting time: 4
Average Turn Around time:8