Consider an array arr
.
s1
and s2
are any two sub sets of our original array arr
. We should partition our original array such that these two sub sets have the minimum difference, i.e., min(sum(s1) - sum(s2))
where sum(s1) >= sum(s2)
.
I'm supposed to print these two sub sets, i.e., s1
and s2
, as my output.
You can store these sub sets in a vector.
For example if arr[] = [0,1,5,6]
, then the minimal difference is 0
and my two sub sets are s1[] = [0,1,5]
and s2[] = [6]
.
Another example could be arr[] = [16,14,13,13,12,10,9,3]
, and the two sub sets would be s1[]=[16,13,13,3]
and s2[] = [14,12,10,9]
with a minimum difference of 0
again.
I can't seem to figure out how to get to these two sub sets.
Much appreciated!
Note: I know how to obtain the minimum difference from the two sub sets using DP but I am unable to proceed further. It's getting the two sub sets (with the minimal difference) that I'm unable to do. Just an algorithm with a nudge along the right direction would do.
#include<iostream>
#include<vector>
using namespace std;
int min_subset_sum_diff(int a[], int n,int sum) {
vector<vector<bool>> go(n + 1, vector<bool>(sum + 1, false));
for (int i = 0; i < n + 1; ++i) {
go[i][0] = true;
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= sum; ++j) {
if (a[i - 1] <= j) {
go[i][j] = go[i - 1][j - a[i - 1]] || go[i - 1][j];
}
else {
go[i][j] = go[i - 1][j];
}
}
}
for (int j = (sum / 2); j >= 0; --j) {
if (go[n][j]) { // only need the last row as I need all the elements, which is n
return sum - 2 * j;
}
}
return INT_MAX;
}
int main() {
int a[] = { 3,100,4,4 };
int n = sizeof(a) / sizeof(a[0]);
int sum = 0;
for (auto i : a) {
sum += i;
}
cout << min_subset_sum_diff(a, n,sum);
}
s1 = sum(first_subset)
s2= sum(second_subset)
Assuming s2>=s1
,
s1 + s2 = sum_arr
s2 = sum_arr - s1 //using this in the next equation
s2-s1 = difference
(sum_arr - s1) - s1 = difference
sum_arr - 2*s1 = difference
This is my underlying logic.
sum(s1)
and sum(s2)
lie between 0..sum_arr
Since I assume s1 < s2
, s1 can have values only between 0..(sum_arr/2)
And my aim is to minimum value of sum_arr - 2*s1
, this will be true for the largest s1
that is true