Minimum absolute difference of server loads

There are some processes that need to be executed. The amount of load that process causes a server that runs it, is being represented by a single integer. The total load caused on a server is the sum of the loads of all the processes that run on that server. You have at your disposal two servers, on which the mentioned processes can be run. Your goal is to distribute given processes between those two servers in the way that, the absolute difference of their loads will be minimized. 
Given an array of A[] of N integers, which represents loads caused by successive processes, the task is to print the minimum absolute difference of server loads. 
Examples:

Input: A[] = {1, 2, 3, 4, 5} 
Output:
Explanation: 
Distribute the processes with loads {1, 2, 4} on the first server and {3, 5} on the second server, so that their total loads will be 7 and 8, respectively. 
The difference of their loads will be equal to 1.

Input: A[] = {10, 10, 9, 9, 2} 
Output: 0

Naive Approach: The simplest approach to solve the problem is to generate all possibilities of the load distribution and find the minimum difference possible among all the possible combinations of loads of the two servers.

Time Complexity: O(2N
Auxiliary Space: O(1)

Efficient Approach: The problem can be visualized as a variation of the 0/1 Knapsack problem in which 2 servers are given, and we have to distribute the loads as equally possible. Therefore, it can be solved using Dynamic Programming. Below are the steps:



  • Compute required_load, which is equal to (sum of all loads / 2), since the loads need to distributed as equally possible.
  • Create a memoization table DP[][] to consider all the possible server loads in the range [1, required_load].
  • The state DP[i][j] stores the maximum value of j – load considering up to the ith element. So, considering li(load in ith row), it can be filled in all the columns having load values > li.
  • Now two possibilities arise, either to fill li in the given column or not.
  • Now, take a maximum of the above two possibilities, i.e.

    DP[i][j] = max(DP[i – 1][j], DP[i – 1][j – li] + li]

  • Finally, DP[n][required_load] will contain the load on server1 which is as balanced as possible.

Below is the implementation of the above approach:

C++14

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++14 program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
  
// Function which returns the minimum
// difference of loads
int minServerLoads(int n, vector<int>& servers)
{
      
    // Compute the overall server load
    int totalLoad = 0;
    for(int i : servers) totalLoad += i;
  
    int requiredLoad = totalLoad / 2;
  
    // Stores the results of subproblems
    vector<vector<int>> dp(n + 1,
    vector<int>(requiredLoad + 1, 0));
  
    // Fill the partition table
    // in bottom up manner
    for(int i = 1; i < n + 1; i++)
    {
        for(int j = 1; j < requiredLoad + 1; j++)
        {
              
            // If i-th server is included
            if (servers[i - 1] > j)
                dp[i][j] = dp[i - 1][j];
  
            // If i-th server is excluded
            else
                dp[i][j] = max(dp[i - 1][j],
                          servers[i - 1] +
                        dp[i - 1][j - servers[i - 1]]);
        }
    }
  
    // Server A load: total_sum-ans
    // Server B load: ans
    // Diff: abs(total_sum-2 * ans)
    return totalLoad - 2 * dp[n][requiredLoad];
}
  
// Driver Code
int main()
{
    int N = 5;
      
    vector<int> servers = { 1, 2, 3, 4, 5 };
      
    // Function call
    cout << (minServerLoads(N, servers));
}
  
// This code is contributed by mohit kumar 29

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to implement
// the above approach
import java.util.*;
class GFG {
  
    // Function which returns the minimum
    // difference of loads
    static int minServerLoads(int n, int[] servers)
    {
        // Compute the overall server load
        int totalLoad = 0;
        for (int i = 0; i < servers.length; i++)
            totalLoad += servers[i];
        int requiredLoad = totalLoad / 2;
  
        // Stores the results of subproblems
        int dp[][] = new int[n + 1][requiredLoad + 1];
  
        // Fill the partition table
        // in bottom up manner
        for (int i = 1; i < n + 1; i++) 
        {
            for (int j = 1; j < requiredLoad + 1; j++) 
            {
                // If i-th server is included
                if (servers[i - 1] > j)
                    dp[i][j] = dp[i - 1][j];
  
                // If i-th server is excluded
                else
                    dp[i][j] = Math.max(dp[i - 1][j],
                                        servers[i - 1] + 
                                        dp[i - 1][j - servers[i - 1]]);
            }
        }
  
        // Server A load: total_sum-ans
        // Server B load: ans
        // Diff: abs(total_sum-2 * ans)
        return totalLoad - 2 * dp[n][requiredLoad];
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        int N = 5;
        int servers[] = {1, 2, 3, 4, 5};
  
        // Function call
        System.out.print(minServerLoads(N, servers));
    }
}
  
// This code is contributed by Chitranayal

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program for the above approach
  
# Function which returns the minimum
# difference of loads
def minServerLoads(n, servers):
  
    # Compute the overall server load
    totalLoad = sum(servers)
  
    requiredLoad = totalLoad // 2
  
    # Stores the results of subproblems
    dp = [[0 for col in range(requiredLoad + 1)]
          for row in range(n + 1)]
  
    # Fill the partition table
    # in bottom up manner
    for i in range(1, n + 1):
        for j in range(1, requiredLoad + 1):
  
            # If i-th server is included
            if servers[i-1] > j:
                dp[i][j] = dp[i-1][j]
  
            # If i-th server is excluded
            else:
                dp[i][j] = max(dp[i-1][j], 
                           servers[i-1] +
                           dp[i-1][j-servers[i-1]])
  
    # Server A load: total_sum-ans
    # Server B load: ans
    # Diff: abs(total_sum-2 * ans)
    return totalLoad - 2 * dp[n][requiredLoad]
  
# Driver Code
  
N = 5;
  
servers = [1, 2, 3, 4, 5]
  
# Function Call
print(minServerLoads(N, servers))

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to implement
// the above approach
using System;
  
class GFG{
  
// Function which returns the minimum
// difference of loads
static int minServerLoads(int n, int[] servers)
{
      
    // Compute the overall server load
    int totalLoad = 0;
    for(int i = 0; i < servers.Length; i++)
        totalLoad += servers[i];
          
    int requiredLoad = totalLoad / 2;
  
    // Stores the results of subproblems
    int [,]dp = new int[n + 1, requiredLoad + 1];
  
    // Fill the partition table
    // in bottom up manner
    for(int i = 1; i < n + 1; i++) 
    {
        for(int j = 1; j < requiredLoad + 1; j++) 
        {
              
            // If i-th server is included
            if (servers[i - 1] > j)
                dp[i, j] = dp[i - 1, j];
  
            // If i-th server is excluded
            else
                dp[i, j] = Math.Max(dp[i - 1, j],
                               servers[i - 1] + 
                                    dp[i - 1, j - 
                               servers[i - 1]]);
        }
    }
  
    // Server A load: total_sum-ans
    // Server B load: ans
    // Diff: abs(total_sum-2 * ans)
    return totalLoad - 2 * dp[n, requiredLoad];
}
  
// Driver Code
public static void Main(string[] args)
{
    int N = 5;
    int []servers = { 1, 2, 3, 4, 5 };
  
    // Function call
    Console.Write(minServerLoads(N, servers));
}
}
  
// This code is contributed by rutvik_56

chevron_right


Output: 

1

Time Complexity: O(N*S) where N is the number of servers and S is the sum of the load all servers. 
Auxiliary Space: O(N*S)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

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.