Skip to content
Related Articles

Related Articles

Improve Article

Minimum absolute difference of server loads

  • Difficulty Level : Medium
  • Last Updated : 14 Jun, 2021

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 a 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.

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.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

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




// 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

Java




// 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

Python3




# 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))

C#




// 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

Javascript




<script>
 
// JavaScript program to implement
// the above approach
 
// Function which returns the minimum
// difference of loads
function minServerLoads(n, servers)
{
     
    // Compute the overall server load
    var totalLoad = 0;
 
    servers.forEach(i => {
        totalLoad+=i;
    });
 
    var requiredLoad = parseInt(totalLoad / 2);
 
    // Stores the results of subproblems
    var dp =
    Array.from(Array(n+1), ()=> Array(requiredLoad+1).fill(0));
 
    // Fill the partition table
    // in bottom up manner
    for(var i = 1; i < n + 1; i++)
    {
        for(var 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
var N = 5;
var servers = [1, 2, 3, 4, 5];
 
// Function call
document.write(minServerLoads(N, servers));
 
 
</script>
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)




My Personal Notes arrow_drop_up
Recommended Articles
Page :