Find the Time Taken Finish Processing of given Processes


Given are N processes and two N−sized arrays, arr1[] and arr2[]. A process's time in the critical section is recorded in arr1[], and it’s time to finish processing after leaving the critical part is recorded in arr2. The goal is to determine how long it will take for each process to finish processing (both inside and outside of the critical section) in any given order.

Input Output Scenarios

Assume we have 3 arrays as shown below

Input

N = 3, arr1[] = {1, 4, 3}, arr2[] = {2, 3, 1}

Output

9
  • The first process, at time 0, it reaches the critical section. The work in the critical section is thus finished after 1 unit of time, and it takes 2 more units outside the critical section. So the total time after which 1st process is finished is 3 units.

  • The second process enters the critical section after one unit of time and exits it after 5th unit. After spending 3 units of time outside the crucial part, the task is eventually completed after eight units of time.

  • The third procedure involves accessing the crucial section after 5 units and leaving after 8th. Then spend 1 more unit outside the critical section is finished after 9 units of time from the start of all the processes. So the total time taken is 9.

Algorithm

We need to take into account how long each process spends in the critical section as well as how long it takes to finish processing after leaving the critical section in order to calculate the overall time required by all processes. To determine the overall amount of time spent, we can use the algorithm below:

  • Initialize a variable 'time' to 0, which will store the total time taken.

  • Create a new array 'finishTime[]' of size N, which will store the time at which each process finishes processing.

  • Initialize all elements of 'finishTime[]' to 0.

  • Find the process with the minimum time spent in the critical section, and let it processes i.

  • Add arr1[i] to time, which is the time taken by process i to complete the critical section task.

  • Add arr2[i] to time, which is the time taken by process i to complete processing after coming out of the critical section.

  • Update finishTime[i] to the current value of time.

  • Set arr1[i] and arr2[i] to infinity to mark process i as completed.

  • Repeat steps 4−8 until all processes have been completed.

Find the maximum value in the 'finishTime[]' array, which will be the total time taken by all the processes.

Java Implementation

Here is the Java implementation for the same

Example

public class Demo{
   public static int total_time(int N, int[] arr1, int[] arr2) {
      int time = 0;
      int[] finishTime = new int[N];      
	  while (true) {
         int minArr1 = Integer.MAX_VALUE;
         int i = -1;
         for (int j = 0; j < N; j++) {
            if (arr1[j] < minArr1) {
                minArr1 = arr1[j];
                i = j;
            }
        }
        if (i == -1) {
            break;
        }
        time += arr1[i] + arr2[i];
        finishTime[i] = time;
        arr1[i] = Integer.MAX_VALUE;
        arr2[i] = Integer.MAX_VALUE;
      }

      int maxFinishTime = Integer.MIN_VALUE;
      for (int i = 0; i < N; i++) {
         if (finishTime[i] > maxFinishTime) {
          maxFinishTime = finishTime[i];
        }
      }
      return maxFinishTime;
   }
   public static void main(String args[]){
      int N = 3;
      int[] arr1 = {1, 4, 3};
      int[] arr2 = {2, 3, 1};
      System.out.println(total_time(N, arr1, arr2));
   }
}

Output

14

The time complexity of the above algorithm, where N is the total number of processes, is O(N2). This is because we scan the entire arr1[] array at each iteration of the loop to decide how much time needs to be spent in the important region. This scanning takes place N times in O(N) time, yielding a time complexity of O(N2).

The technique has an O(N) space complexity since we use an array of size N to store how long each operation took to complete. The complexity of the total space is not increased by the other variables in the algorithm (time, minArr1, and i), as they all need a fixed amount of space.

Optimized approach

The time complexity of the algorithm can be optimized by using a priority queue (or a min−heap) instead of scanning the entire arr1[] array to find the minimum time spent in the critical section.

We can create a min heap to store the time spent in the critical section for each process. We then repeatedly extract the minimum time spent in the critical section from the heap, add it to the total time, and calculate the finish time for that process. We update the finish time for that process and insert it back into the heap. We repeat this process until the heap is empty.

Using a heap allows us to find the minimum time spent in the critical section in O(log N) time instead of O(N) time, reducing the overall time complexity of the algorithm to O(N log N).

Algorithm

Here are the detailed steps of the optimized algorithm:

  • Create an integer variable time and initialize it to 0. This variable will keep track of the total time taken by all the processes.

  • Create an integer array finishTime of size N and initialize all its elements to 0. This array will store the finish time for each process.

  • Create a PriorityQueue object pq to store the time spent in the critical section for each process. Add all the elements of arr1[] to the queue.

  • While the queue is not empty, do the following:

    • Remove the minimum element from the queue using pq.remove() and store it in a variable minArr1.

    • Find the index i of the element in arr1[] that has the value minArr1. We can do this by scanning arr1[] linearly and finding the first element that matches minArr1.

    • Add minArr1 and the corresponding value of arr2[] for process i to the time variable. This gives us the total time taken by process i.

    • Store the total time taken by process i in finishTime[i].

    • Set arr1[i] and arr2[i] to Integer.MAX_VALUE to prevent them from being taken into account during the next iteration of the loop.

    • Add all of the remaining arr1[] entries to the queue except from the ones with an integer value.MAX_VALUE.

  • Find the maximum value in the finishTime[] array and return it. This gives us the total time taken by all the processes to complete their processing.

The main improvement in this technique is the use of a priority queue to determine teh minimum time spent in critical section in in O(log N) time rather than having to scan the full arr1[] array in O(N) time. This reduces the algorithm's overall time complexity to O(N log N).

Java Implementation

Here is the Java implementation for the same

Example

 import java.util.PriorityQueue;
public class Demo{
   public static int total_time(int N, int[] arr1, int[] arr2) {
      int time = 0;
      int[] finishTime = new int[N];
      PriorityQueue<Integer> pq = new PriorityQueue<>();
      for (int i = 0; i < N; i++) {
         pq.add(arr1[i]);
      }
      while (!pq.isEmpty()) {
         int minArr1 = pq.remove();
         int i = -1;
         for (int j = 0; j < N; j++) {
            if (arr1[j] == minArr1) {
               i = j;
               break;
            }
         }
	   if( i!= -1){
         	time += minArr1 + arr2[i];
         	finishTime[i] = time;
         	arr1[i] = Integer.MAX_VALUE;
         	arr2[i] = Integer.MAX_VALUE;
         	for (int j = 0; j < N; j++) {
            	if (arr1[j] != Integer.MAX_VALUE) {
               		pq.add(arr1[j]);
            	}
         	}
 }
      }
      int maxFinishTime = Integer.MIN_VALUE;
      for (int i = 0; i < N; i++) {
         if (finishTime[i] > maxFinishTime) {
            maxFinishTime = finishTime[i];
         }
      }
      return maxFinishTime;
   }
   public static void main(String args[]){
      int N = 3;
      int[] arr1 = {1, 4, 3};
      int[] arr2 = {2, 3, 1};
      System.out.println(total_time(N, arr1, arr2)); 
   }
}

Output

14

Updated on: 22-Aug-2023

29 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements