Minimize the Absolute Difference of Sum of Two Subsets


To Minimize the Absolute Difference of Sum of Two Subsets, we partition a vector into two subsets i.e. we divide the elements of the vector into two smaller vectors such that each element of the original vector belongs to one of the two smaller vectors, and the two smaller vectors are disjoint.

For example, if we have a vector v = {1, 2, 3, 4, 5}, then one possible partitioning of v into two subsets is S1 = {1, 3, 4} and S2 = {2, 5}, where each element of v belongs to either S1 or S2, and the intersection of S1 and S2 is the empty set.

The goal of this article is to partition the list in such a way that the absolute difference of subsets sum is minimum.

Problem Statement

The task at hand is to partition a list of integers into two subsets S1 and S2, in such a way that the difference between the sum of elements of S1 and the sum of elements of S2 is as small as possible.

Sample Examples

Input

{1, 2, 7}

Output

4

Explanation

The two partitions with minimum absolute difference are {1, 2} and {7}. Their subset sums are 3 and 7, respectively, and their absolute difference is 4.

Input

{10, 20, 15, 5, 25}

Output

5

Explanation

The two partitions with minimum absolute difference are {10, 20, 5} and {15, 25}. Their subset sums are 35 and 40, respectively, and their absolute difference is 5.

Input

{1, 1, 1, 1, 1}

Output

0

Explanation

The two partitions with minimum absolute difference are {1, 1, 1} and {1, 1, 1}. Their subset sums are both 3, and their absolute difference is 0.

Solution Approach

The underlying logic of this method is to use dynamic programming to find a subset of the given set of integers whose sum is as close as possible to half the total sum of the set. This is done by creating a 2D boolean array where dp[i][j] indicates if there exists a subset of the first i elements with sum j. Then, we check for all values up to half the total sum of the set if there exists a subset with that sum. Finally, we compute the minimum absolute difference between the total sum and twice the sum of the subsets with the sum closest to half the total sum.

The solution approach of the given program consists of the following steps:

  • Calculate the sum of all elements in the input array.

  • Create a 2D boolean vector of size (n+1)x(range+1) and initialize all its values to false, where n is the size of the input array and range is the sum of all its elements.

  • Set the value of dp[i][0] to true for all i from 0 to n.

  • Loop through the rows and columns of the 2D boolean vector and set the value of dp[i][j] to the logical OR of dp[i-1][j] and dp[i-1][j-arr[i-1]], where arr is the input array, i is the current row, and j is the current column.

  • Create a vector to store the valid values of subset sum, i.e., the values of j for which dp[n][j] is true.

  • Loop through half of the range and add all the valid values of subset sum to the valid vector.

  • Loop through the valid vector and set the value of mini to the minimum value of mini and (range - (2 * valid[i])), where mini is initialized to the maximum value of an integer.

  • Return the value of mini as the minimum absolute difference between the two subset partitions of the input array.

Algorithm

  • Function minDifference()

    • Initialize range = 0

    • for i from 0 to n - 1

      range = range + arr[i]

    • Initialize dp matrix

    • for i from 0 to n

      Set dp[i][0] = true

    • for i from 1 to n

      for j from 1 to range

      if arr[i - 1] <= j

      dp[i][j] = dp[i - 1][j] || dp[i - 1][j - arr[i - 1]];

      else

      dp[i][j] = dp[i - 1][j];

    • Initialize boolean vector valid

    • for i from 0 to range / 2

      if (dp[n][i] == true)

      valid.push_back(i);

    • Initialize mini = INT_MAX;

    • for i from 0 to valid.size() - 1

      mini = min (mini, range - (2 * valid[i]))

    • return mini

  • Function main()

    • Initialize integer vector a

    • Initialize n = a.size();

    • Function call minDifference(a, n);

    • Print result

Example : C++ Program

The following C++ program uses a dynamic programming approach to find the minimum absolute difference between 2 subset sums in an array. The function minDifference() calculates the total sum of all the elements in the list. We then initialize and fill the dp matrix. We create a vector valid which consists of all possible subset sums and then return the answer.

// C++ program to return the minimum absolute difference between 2 subset partitions of array
#include <bits/stdc++.h>
using namespace std;
// function to calculate minimum difference of subset sums
int minDifference(vector<int> arr, int n) {
    // Calculate the range of the array
    int range = 0;
    for (int i = 0; i < n; i++) {
        range += arr[i];
    }
    // Initialize the dp matrix
    vector<vector<bool>> dp(n + 1, vector<bool>(range + 1, 0));
    for (int i = 0; i <= n; i++) {
        dp[i][0] = true;
    }
    // Fill the dp matrix
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= range; j++) {
            if (arr[i - 1] <= j) {
                dp[i][j] = dp[i - 1][j] || dp[i - 1][j - arr[i - 1]];
            } else {
                dp[i][j] = dp[i - 1][j];
            }
        }
    }
    // Find the valid subset sums
    vector<int> valid;
    for (int i = 0; i <= range / 2; i++) {
        if (dp[n][i] == true) {
            valid.push_back(i);
        }
    }
    // Calculate the minimum absolute difference
    int mini = INT_MAX;
    for (int i = 0; i < valid.size(); i++) {
        mini = min(mini, range - (2 * valid[i]));
    }
    return mini;
}
// driver code
int main() {
    // Input array
    vector<int> a = {1, 2, 7};
    int n = a.size();
    // Calculate the minimum subset difference
    int result = minDifference(a, n);
    cout << "Minimum Subset Difference is: " << result << endl;
    return 0;
}

Output

Minimum Subset Difference is: 4

Time and Space Complexity Analysis

Time Complexity: O(n2)

  • The program uses a nested loop to fill in the dp matrix, so the time complexity of the dp filling step is O(n * range).

  • The program uses a loop to find the valid subset sums, so the time complexity of the subset sum checking step is O(range/2).

  • The program uses a loop to calculate the minimum absolute difference, so the time complexity of this step is O(valid.size()).

  • Therefore, the overall time complexity of the program is O(n * range + range/2 + valid.size()).

Space Complexity: O(n2)

  • The program uses a 2D boolean array dp of size (n+1)x(range+1), so the space complexity of the dp matrix is O(n * range).

  • The program uses a vector valid to store the valid subset sums, so the space complexity of the valid vector is O(range/2).

  • Therefore, the overall space complexity of the program is O(n * range).

Conclusion

In this article, we discussed a dynamic programming approach to find the absolute minimum difference between 2 partition subsets of an array. The problem statement was well-defined with the help of suitable examples. The article also discussed the solution approach, algorithm, C++ program code, and the time and space complexity in great detail.

Updated on: 08-Sep-2023

156 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements