After experimenting a little, I have convinced myself that simply computing all the 2^n sums and storing them is the best approach. However, the efficicieny of implementing a small set is crucial to avoid that the computation of these sums which is of O(2^n*n) takes too long.
I have used the integers 0 to 2^n-1 to represent the set of all subsets (powerset).
public class Sum {
private Map<Integer,List<Integer>> sum2sets = new HashMap<>();
private int n;
private int max;
private int[] theSet;
public Sum( int[] theSet ){
this.theSet = theSet;
int n = theSet.length;
max = (1 << n) - 1;
int maxSum = n*(n+1)/2;
}
Thus, a sum can be computed with the loop
private int sum( int n ){
int s = 0;
for( int i = 0; n > 0; i++ ){
if( (n & 1) != 0 ) s += theSet[i];
n = n >> 1;
}
return s;
}
The computation of all subsets with equal sums is simple:
public void buildLists(){
int maxlen = 0;
int maxsum = 0;
for( int i = 0; i <= max; i++ ){
int s = sum( i );
List<Integer> set = sum2sets.get( s );
if( set == null ){
set = new ArrayList<Integer>();
sum2sets.put( s, set );
}
set.add( i );
int len = sum2sets.size();
if( len > maxlen ){
maxsum = s;
maxlen = len;
}
}
System.out.println( "max. len " + maxlen + " at " + maxsum );
}
The result set of sets with equal sum varies. Successive integers 1, 2,... 20 will produce long lists of sets producing certain sums, e.g. for sum 105 there are 15272 sets.
A selection of: 3, 7, 13, 18, 21, 22, 30, 34, 42, 49, 50, 61, 65, 67, 70, 71, 88, 91, 93, 99 has a maximum number of sets equal to 963 for the sum 994.
Further processing of this map depends on what OP really wants - there have been some questions in the comments.
You can, for instance, find pairs of subsets with the same sum, disjoint or not, but these numbers will be very large.
public String setAsString( int n ){
StringBuilder sb = new StringBuilder( "[" );
String del = "";
for( int i = 0; n > 0; i++ ){
if( (n & 1) != 0 ){
sb.append( del ).append( theSet[i] );
del = ", ";
}
n = n >> 1;
}
sb.append( "]" );
return sb.toString();
}
public void dumpAll( int n ){
for( Map.Entry<Integer,List<Integer>> e: sum2sets.entrySet() ){
int sum = e.getKey();
List<Integer> sets = e.getValue();
if( sets.size() >= 2 ){
System.out.println( "sum: " + sum );
for( Integer i: sets ){
System.out.print( " " + setAsString( i ) );
}
System.out.println();
if( --n == 0 ) break;
}
}
}
This is the main method, to run an example.
public static void main( String[] args ){
int[] nums = new int[]{
3, 7, 13, 18, 21, 22, 30, 34, 42, 49,
50, 61, 65, 67, 70, 71, 88, 91, 93, 99 };
Sum sum = new Sum( nums );
sum.buildLists();
sum.dumpAll( 50 );
}
And the glorious output (just a small subset):
max. len 963 at 994
sum: 21
[3, 18] [21]
sum: 25
[7, 18] [3, 22]
sum: 28
[3, 7, 18] [7, 21]
sum: 31
[13, 18] [3, 7, 21]
sum: 34
[3, 13, 18] [13, 21] [34]
sum: 37
[3, 13, 21] [7, 30] [3, 34]
sum: 38
[7, 13, 18] [3, 13, 22]
sum: 40
[18, 22] [3, 7, 30]
sum: 41
[3, 7, 13, 18] [7, 13, 21] [7, 34]
sum: 42
[3, 18, 21] [7, 13, 22] [42]
sum: 43
[3, 18, 22] [21, 22] [13, 30]
sum: 44
[3, 7, 13, 21] [3, 7, 34]
sum: 45
[3, 7, 13, 22] [3, 42]
sum: 46
[7, 18, 21] [3, 21, 22] [3, 13, 30]
sum: 47
[7, 18, 22] [13, 34]
sum: 49
[3, 7, 18, 21] [7, 42] [49]
sum: 50
[3, 7, 18, 22] [7, 21, 22] [7, 13, 30] [3, 13, 34] [50]
sum: 51
[3, 18, 30] [21, 30]
sum: 52
[13, 18, 21] [22, 30] [18, 34] [3, 7, 42] [3, 49]
sum: 53
[13, 18, 22] [3, 7, 21, 22] [3, 7, 13, 30] [3, 50]
sum: 54
[3, 21, 30] [7, 13, 34]
sum: 55
[3, 13, 18, 21] [7, 18, 30] [3, 22, 30] [3, 18, 34] [21, 34] [13, 42]
sum: 56
[3, 13, 18, 22] [13, 21, 22] [22, 34] [7, 49]
sum: 57
[3, 7, 13, 34] [7, 50]
sum: 58
[3, 7, 18, 30] [7, 21, 30] [3, 21, 34] [3, 13, 42]
sum: 59
[7, 13, 18, 21] [3, 13, 21, 22] [7, 22, 30] [7, 18, 34] [3, 22, 34] [3, 7, 49]
sum: 60
[7, 13, 18, 22] [18, 42] [3, 7, 50]
sum: 61
[18, 21, 22] [13, 18, 30] [3, 7, 21, 30] [61]
sum: 62
[3, 7, 13, 18, 21] [3, 7, 22, 30] [3, 7, 18, 34] [7, 21, 34] [7, 13, 42] [13, 49]
sum: 63
[3, 7, 13, 18, 22] [7, 13, 21, 22] [7, 22, 34] [3, 18, 42] [21, 42] [13, 50]
sum: 64
[3, 18, 21, 22] [3, 13, 18, 30] [13, 21, 30] [30, 34] [22, 42] [3, 61]
sum: 65
[13, 22, 30] [13, 18, 34] [3, 7, 21, 34] [3, 7, 13, 42] [3, 13, 49] [65]
sum: 66
[3, 7, 13, 21, 22] [3, 7, 22, 34] [3, 21, 42] [3, 13, 50]
sum: 67
[3, 13, 21, 30] [3, 30, 34] [7, 18, 42] [3, 22, 42] [18, 49] [67]
sum: 68
[7, 18, 21, 22] [7, 13, 18, 30] [3, 13, 22, 30] [3, 13, 18, 34] [13, 21, 34] [18, 50] [7, 61] [3, 65]
sum: 69
[18, 21, 30] [13, 22, 34] [7, 13, 49]
sum: 70
[18, 22, 30] [3, 7, 18, 42] [7, 21, 42] [3, 18, 49] [21, 49] [7, 13, 50] [3, 67] [70]
sum: 71
[3, 7, 18, 21, 22] [3, 7, 13, 18, 30] [7, 13, 21, 30] [3, 13, 21, 34] [7, 30, 34] [7, 22, 42] [22, 49] [3, 18, 50] [21, 50] [3, 7, 61] [71]
sum: 72
[3, 18, 21, 30] [7, 13, 22, 30] [7, 13, 18, 34] [3, 13, 22, 34] [30, 42] [3, 7, 13, 49] [22, 50] [7, 65]
sum: 73
[3, 18, 22, 30] [21, 22, 30] [18, 21, 34] [13, 18, 42] [3, 7, 21, 42] [3, 21, 49] [3, 7, 13, 50] [3, 70]
sum: 74
[13, 18, 21, 22] [3, 7, 13, 21, 30] [18, 22, 34] [3, 7, 30, 34] [3, 7, 22, 42] [7, 18, 49] [3, 22, 49] [3, 21, 50] [13, 61] [7, 67] [3, 71]
sum: 75
[3, 7, 13, 22, 30] [3, 7, 13, 18, 34] [7, 13, 21, 34] [3, 30, 42] [7, 18, 50] [3, 22, 50] [3, 7, 65]
sum: 76
[7, 18, 21, 30] [3, 21, 22, 30] [3, 18, 21, 34] [7, 13, 22, 34] [3, 13, 18, 42] [13, 21, 42] [34, 42]
sum: 77
[3, 13, 18, 21, 22] [7, 18, 22, 30] [3, 18, 22, 34] [21, 22, 34] [13, 30, 34] [13, 22, 42] [3, 7, 18, 49] [7, 21, 49] [3, 13, 61] [3, 7, 67] [7, 70]
sum: 78
[3, 7, 13, 21, 34] [7, 22, 49] [3, 7, 18, 50] [7, 21, 50] [13, 65] [7, 71]
sum: 79
[3, 7, 18, 21, 30] [3, 7, 13, 22, 34] [3, 13, 21, 42] [7, 30, 42] [3, 34, 42] [30, 49] [7, 22, 50] [18, 61]
sum: 80
[3, 7, 18, 22, 30] [7, 21, 22, 30] [7, 18, 21, 34] [3, 21, 22, 34] [3, 13, 30, 34] [7, 13, 18, 42] [3, 13, 22, 42] [13, 18, 49] [3, 7, 21, 49] [30, 50] [13, 67] [3, 7, 70]
sum: 81
[7, 13, 18, 21, 22] [7, 18, 22, 34] [18, 21, 42] [3, 7, 22, 49] [13, 18, 50] [3, 7, 21, 50] [7, 13, 61] [3, 13, 65] [3, 7, 71]
sum: 82
[13, 18, 21, 30] [18, 30, 34] [18, 22, 42] [3, 7, 30, 42] [3, 30, 49] [3, 7, 22, 50] [3, 18, 61] [21, 61]
sum: 83
[13, 18, 22, 30] [3, 7, 21, 22, 30] [3, 7, 18, 21, 34] [3, 7, 13, 18, 42] [7, 13, 21, 42] [7, 34, 42] [3, 13, 18, 49] [13, 21, 49] [34, 49] [3, 30, 50] [22, 61] [18, 65] [3, 13, 67] [13, 70]