Minimum absolute difference of server loads

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: 1 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
Java
Python3
C#
Javascript
// C++14 program to implement// the above approach#include <bits/stdc++.h>using namespace std; // Function which returns the minimum// difference of loadsint 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 Codeint 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 program to implement// the above approachimport 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 program for the above approach # Function which returns the minimum# difference of loadsdef 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 Callprint(minServerLoads(N, servers))
// C# program to implement// the above approachusing System; class GFG{ // Function which returns the minimum// difference of loadsstatic 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 Codepublic 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
<script> // JavaScript program to implement// the above approach // Function which returns the minimum// difference of loadsfunction 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 Codevar N = 5;var servers = [1, 2, 3, 4, 5]; // Function calldocument.write(minServerLoads(N, servers));  </script>
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)
mohit kumar 29
ukasp
rutvik_56
rrrtnx
Google
interview-preparation
knapsack
subsequence
Arrays
Dynamic Programming
Mathematical
Searching
Google
Arrays
Searching
Dynamic Programming
Mathematical
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.