Schedule jobs so that each server gets equal load

There are n servers. Each server i is currently processing a(i) amount of requests. There is another array b in which b(i) represents number of incoming requests that are scheduled to server i. Reschedule the incoming requests in such a way that each server i holds equal amount of requests after rescheduling. An incoming request to server i can be rescheduled only to server i-1, i, i+1. If there is no such rescheduling possible then output -1 else print number of requests hold by each server after resheduling.

Examples:

Input : a = {6, 14, 21, 1}
        b = {15, 7, 10, 10}
Output : 21
b(0) scheduled to a(0) --> a(0) = 21
b(1) scheduled to a(1) --> a(1) = 21
b(2) scheduled to a(3) --> a(3) = 11
b(3) scheduled to a(3) --> a(3) = 21
a(2) remains unchanged --> a(2) = 21

Input : a = {1, 2, 3}
        b = {1, 100, 3}
Output : -1
No rescheduling will result in equal requests.

Approach: Observe that each element of array b is always added to any one element of array a exactly once. Thus sum of all elements of array b + sum of all elements of old array a = sum of all elements of new array a. Let this sum be S. Also all the elements of new array a are equal. Let each new element is x. If array a has n elements, this gives



 x * n = S
  => x = S/n     ....(1)

Thus all the equal elements of new array a is given by eqn(1). Now to make each a(i) equals to x we need to add x-a(i) to each element. We will iterate over entire array a and check whether a(i) can be made equal to x. There are multiple possibilities:
1. a(i) > x: In this case a(i) can never be made equal to x. So output -1.
2. a(i) + b(i) + b(i+1) = x. Simply add b(i) + b(i+1) to a(i) and update b(i), b(i+1) to zero.
3. a(i) + b(i) = x. Add b(i) to a(i) and update b(i) to zero.
4. a(i) + b(i+1) = x. Add b(i+1) to a(i) and update b(i+1) to zero.

After array a is completely traversed, check whether all elements of array b are zero or not. If yes then print a(0) otherwise print -1.

Why b(i) is updated to zero after addition?
Consider a test case in which b(i) is neither added to a(i-1) nor a(i). In that case, we are bounded to add b(i) to a(i+1). Thus while iterating over the array a when we begin performing computations on element a(i), first we add element b(i-1) to a(i) to take into consideration above possibility. Now if b(i-1) is already added to a(i-1) or a(i-2) then in that case it cannot be added to a(i). So to avoid this double addition of b(i) it is updated to zero.

The stepwise algorithm is:

1. Compute sum S and find x = S / n
2. Iterate over array a
3. for each element a(i) do:
   a(i) += b(i-1)
   b(i-1) = 0;
   if a(i) > x:
      break
   else:
     check for other three possibilities
     and update a(i) and b(i).
4. Check whether all elements of b(i) are
   zero or not.

Implementation:

filter_none

edit
close

play_arrow

link
brightness_4
code

// CPP program to schedule jobs so that
// each server gets equal load.
#include <bits/stdc++.h>
using namespace std;
  
// Function to find new array a
int solve(int a[], int b[], int n)
{
    int i;
    long long int s = 0;
  
    // find sum S of both arrays a and b.
    for (i = 0; i < n; i++) 
        s += (a[i] + b[i]);    
  
    // Single element case.
    if (n == 1)
        return a[0] + b[0];
  
    // This checks whether sum s can be divided
    // equally between all array elements. i.e.
    // whether all elements can take equal value
    // or not.
    if (s % n != 0)
        return -1;
  
    // Compute possible value of new array 
    // elements.
    int x = s / n;
  
    for (i = 0; i < n; i++) {
  
        // Possibility 1
        if (a[i] > x) 
            return -1;      
  
        // ensuring that all elements of 
        // array b are used.
        if (i > 0) {
            a[i] += b[i - 1];
            b[i - 1] = 0;
        }
  
        // If a(i) already updated to x 
        // move to next element in array a.
        if (a[i] == x)
            continue;
  
        // Possibility 2
        int y = a[i] + b[i];
        if (i + 1 < n)
            y += b[i + 1];
        if (y == x) {
            a[i] = y;
            b[i] = b[i + 1] = 0;
            continue;
        }
  
        // Possibility 3
        if (a[i] + b[i] == x) {
            a[i] += b[i];
            b[i] = 0;
            continue;
        }
  
        // Possibility 4
        if (i + 1 < n && 
            a[i] + b[i + 1] == x) {
            a[i] += b[i + 1];
            b[i + 1] = 0;
            continue;
        }
  
        // If a(i) can not be made equal 
        // to x even after adding all 
        // possible elements from b(i) 
        // then print -1.
        return -1;
    }
  
    // check whether all elements of b 
    // are used.
    for (i = 0; i < n; i++) 
        if (b[i] != 0)
            return -1;    
  
    // Return the new array element value.
    return x;
}
  
int main()
{
    int a[] = { 6, 14, 21, 1 };
    int b[] = { 15, 7, 10, 10 };
    int n = sizeof(a) / sizeof(a[0]);
    cout << solve(a, b, n);
    return 0;
}

chevron_right


  Output: 21

Time Complexity: O(n)
Auxiliary Space : O(1) If we are not allowed to modify original arrays, then O(n)



My Personal Notes arrow_drop_up

A Programmer and A Machine learning Enthusiast

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.




Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.