I\'m working on a solution to a variant of the subset sum problem, using the below code. The problem entails generating subsets of 11 ints from a larger set (superset) and c
One way to only generate unique subsets is to add the elements from the superset in order, and use an additional argument to permute
(eg. supersetPos
) to indicate where you are in the superset. This generates sorted permutations which will be unique.
EDIT: Code that AFAIK runs correctly on your sample:
#include <stdio.h>
int superset[] = {
1, 30, 10, 7, 11,
27, 3, 5, 6, 50,
45, 32, 25, 67, 13,
37, 19, 52, 18, 9
};
int supersetsize = 20;
int endsum = 110;
int done = 0;
int sumOfArray(int array[]) {
int sum = 0;
for(int i = 0; i < 11; i++)
sum += array[i];
return sum;
}
void permute(int subset[], int pos, int sspos) {
if (pos == 11) { //is the current subset 11 ints long?
if (sumOfArray(subset) == endsum) { //if the sum of the array matches the wanted sum, print
for (int j=0; j<11; j++) {
printf("%d ",subset[j]);
}
printf("\n");
done = 1;
}
return;
}
for (int i=sspos; i<supersetsize; i++) {
subset[pos] = superset[i];
permute(subset,pos+1,i+1);
if (done) { //when a correct solution has been found, stop recursion
return;
}
}
}
int main() {
int subset[11] = {0};
permute(subset, 0, 0);
}
you can try my code ( I tried to only give a psudo code and not to solve your homework completely):
// array is all the numbers you are looking from them
// length is the number of arrays
// pos is the position of the slot you are going to fill
// max is nomber of slots you have to fill (in your case since you are going for the 11 sets you have to set this value as 11
// sum is the sum of all the values selected until now
// searchbegin is the first element you can pick from your array (I'm using this variable to only generate subarrays of the superset (array))
// target is the targetvalue you are looking for.
void generate_all(int []array, int length, int pos,int max, int sum,int searchbegin,int target)
{
if max = pos
if sum = target
printselectedresults();
for i:searchbegin->length-max+pos
if (sum + array[i] < target)
{
addtoresults(i);
generate_all(array,length,pos+1,max,sum+array[i],i+1,target);
removefromresults(i);
}
}
with all this information I think you can easily Implement this code your target language and use it.
in my function all the permutations generated are subarrays of superset so no permutation can be generated twice, and also every one is generated at least one time.
I don't think there is a way to generate the unique subsets in better than exponential time.
To solve subset-sum efficiently you want to use dynamic programming. There are some pseudo-polynomial time algorithms for subset-sum that work this way. This Wikipedia article might help.