Well, here is a simple emulation of the process you described. But I use binary numbers to represent set, this makes manipulation easier. For example, the number 19 is 10011 in binary form: this means that students 0, 3, and 4 are selected (in these positions 1).
First a little helper.
Set<Integer> allSubsets(int set, int subsetSize) {
Set<Integer> result = new HashSet<Integer>();
if (subsetSize == 0) {
result.add(0);
return result;
}
if (set == 0) {
return result;
}
if (set % 2 == 1) {
for (Integer i : allSubsets(set / 2, subsetSize - 1)) {
result.add(i * 2 + 1);
}
}
for (Integer i : allSubsets(set / 2, subsetSize)) {
result.add(i * 2);
}
return result;
}
And the main program. Suggestions are welcome.
int N = 5;
int M = 3;
int Z = 2;
List<Integer> result = new ArrayList<Integer>();
// get all groups of M elements from 'wholeSet'
int wholeSet = (1 << N) - 1;
for (int s : allSubsets(wholeSet, M)) {
// Check all subsets of 'Z' elements from set 's'
boolean valid = true;
for (int t : allSubsets(s, Z)) {
// check if this Z-element subset already was used
for (int past : result) {
// check if 't' is subset of 'past' set
if ((past|t) == past) {
valid = false;
break;
}
}
if (!valid) {
break;
}
}
if (valid) {
// none of Z-element subsets of 's' were used before
result.add(s);
}
}
(, memoization) . , , , , .