3

I need to find combination of combination in JAVA.

I have for instance 6 students in class. Out of them, I need to create combination of 4 people in group, and for each group I can choose an intimate group of 2.

I have to make sure that there are no doubles (order does not matter).! and need to print the 4 people group.

However, this is the hard part:

So defining students with numbers:

If I print out 1234 as one of the combinations, I can't print out1256 as well, since 12 appears both in 1234 and in 1256.

How can I write it in Java?

EDITED

output of ([1,2,3,4,5],3,2) will be:

  1. Combinations without repetition (n=5, r=3) {1,2,3} {1,2,4} {1,2,5} {1,3,4} {1,3,5} {1,4,5} {2,3,4} {2,3,5} {2,4,5} {3,4,5}

  2. deleting repeating groups of 2 elements, will leave me only: {1,2,3} {1,4,5} (i deleted groups that have combinations of 12,13,23,45,14,15 since they already appear in the first two that I have found.

Nikita Rybak
  • 67,365
  • 22
  • 157
  • 181
Dejell
  • 13,947
  • 40
  • 146
  • 229
  • If this is homework, you can at least tag it as such. – Mike Axiak Sep 26 '10 at 22:46
  • 2
    to all homework-obsessed: she's a little old for that :) – Nikita Rybak Sep 26 '10 at 22:47
  • 2
    to _Odelya_: can you post output you expect for 6 students (or for smaller number)? I'm not sure how to interpret question right now (in particular, about 'intimate' groups). – Nikita Rybak Sep 26 '10 at 22:48
  • 2
    Just to make sure I understand: given N items, you want to generate some set of subsets S, each of size M, such that no two items from one subset appear in other subsets? what about the size of S? also, the solution is not unique. – Eyal Schneider Sep 26 '10 at 22:50
  • @Mike, Peter, Nikita - it's not homework.. as Nikita guess I am out of school a long time ago – Dejell Sep 26 '10 at 22:59
  • @Eyal - given N items, I need to generate subsets S each of sized M such no two items of size Z are the same. – Dejell Sep 26 '10 at 23:01
  • 1
    @Odelya: So for example for N=5, M=4, and Z=2, the solutions are of size one (e.g. {{1,2,3,4}}), since any two subsets of size 4 have an intersection of at least 2 items. Right? – Eyal Schneider Sep 26 '10 at 23:05
  • @Eyal I edited my question with an example. Thank you for trying to help! it makes sense what you write – Dejell Sep 26 '10 at 23:13
  • @Nikita I edited my question with an example – Dejell Sep 26 '10 at 23:15
  • I don't understand current example. Why is for example {1,3,4} and {1,2,5} wrong? – stmi Sep 26 '10 at 23:45
  • Perhaps this is what you want: http://stackoverflow.com/questions/2955318/creating-combinations-that-have-no-more-one-intersecting-element/ ? –  Sep 27 '10 at 04:20
  • @stmi - since 1,3,4 has 1,3 combinations that already appear in 1,2,3 – Dejell Sep 27 '10 at 07:03
  • 1
    @Odelya, the explanation you give is ambiguous, since the end result depends on the order of the combinations generated in step 1. E.g. if I iterated through the combinations in reverse order, the end result would be {3,4,5} {1,2,5}. You may want to define a strict iteration order to make the result unambiguous. – Péter Török Sep 27 '10 at 08:48

2 Answers2

1

Ok, here's the simple emulation of the process you described. But I use binary numbers to present set, it makes manipulations easier. For example, number 19 is 10011 in binary form: it means students 0, 3 and 4 are selected (there're 1's in those positions).

A little helper first.

// return all subsets of 'set', having size 'subsetSize'
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;
    }

    // check if 1st element is present
    if (set % 2 == 1) {
        // use 1st element, one less element to collect
        for (Integer i : allSubsets(set / 2, subsetSize - 1)) {
            result.add(i * 2 + 1);
        }
    }
    // not use 1st element
    for (Integer i : allSubsets(set / 2, subsetSize)) {
        result.add(i * 2);
    }

    return result;
}

And 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);
        }
    }

But it may require improvements (like memoization) for big inputs. But for now, since you don't say what kind of input you expect, I assume this is good enough.

Nikita Rybak
  • 67,365
  • 22
  • 157
  • 181
  • Memorization or memoization? :) – Pascal Thivent Sep 27 '10 at 00:05
  • @Pascal After saying 'memorization' for five years, it's difficult to change your habits :) Thanks – Nikita Rybak Sep 27 '10 at 00:10
  • @Odelya 'large numbers' is a vague definition. For example, for input (50, 25, 25) result will contain more than 2^40 sets. More than supercomputer can write in a month. – Nikita Rybak Sep 27 '10 at 07:46
  • @Nikita - how did you calculate 2^40? if I have (40,11,8) how long will it take? – Dejell Sep 27 '10 at 08:01
  • @Odelya - I think it's just a approximation. In his sample problem: r = 25, z = 25.Relate with your main problem, I think it the same as problem enumerate all combination size 25 of 50 distinct number. An the number of result is: C(50,25). I think it surely larger than 2^40 much – coolkid Sep 27 '10 at 10:18
  • @Odelya No program will help you to output C(50,25) result sets for that case, unless it involves elves and magic. That's why we need definition of 'large numbers'. – Nikita Rybak Sep 27 '10 at 16:46
0

Imagine you have a Student object with an equals comparing their Primarykey. In your example, student 1 will return 1, 2 will return 2 and so on.

Put them all in the set, this will ensure that there will be no double.

Iterate though the set by 4 then by 2 and will return you your desired result.

mezzie
  • 1,276
  • 8
  • 14
  • your answer will return sets of 2. I need sets of 4 where there are no 2 doubles. in the most effecient way. i think your way is not ideal – Dejell Sep 26 '10 at 23:28