2

For a given Collection<Object> aCollection, How do I build an ArrayList<OrderedCouple<Object>> with all possible permutations of couples in aCollection (except self-coupling).

For instance, say aCollection is a Set<Team> containing teamA, teamB and teamC, and OrderedCouple is instead a class Game<Team> which constructor receives two team, the host and the guest as arguments. I want to build an ArrayList of all possible Games between Teams. that is, the ArrayList will be the group {new Game(teamA, teamB), new Game(teamA, teamC), new Game(teamB, teamA), new Game(teamB, teamC), new Game(teamC, teamA), new Game(teamC, teamB)} in a random order.

Elist
  • 5,313
  • 3
  • 35
  • 73
  • from itertools.permutations import...oh wait this is java :(( why cant standard API have this stuff. – arynaq Dec 07 '13 at 19:03
  • I think the Guava Library could help you get something fairly easily using Collections2. http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Collections2.html#orderedPermutations(java.lang.Iterable) – umhelp Dec 07 '13 at 19:14

1 Answers1

2

I can't think of a faster way than this:

@Test
public void buildMatchUps() {
    List<String> teams = Arrays.asList("A", "B", "C");
    int s = teams.size() * teams.size() - teams.size();
    List<String> matchUps = new ArrayList<String>(s);
    for(String host : teams) {
        for(String guest : teams) {
            if(host != guest) { // ref comparison, because the objects
                                // come from the same list. Otherwise
                                // equals should be used!
                matchUps.add(host + " : " + guest);
            }
        }
    }
    Collections.shuffle(matchUps);
    for(String matchUp : matchUps) {
        System.out.println(matchUp);
    }
}

prints something like this:

C : A
B : A
A : C
C : B
B : C
A : B
A4L
  • 17,353
  • 6
  • 49
  • 70
  • Be aware though that this code runs in `O(n^2)`. More specifically with `k = teams.size()`, it runs in `O(n^k)`. But for small teams and small amount of set numbers (2 teams in this case), it will work fine. – skiwi Dec 07 '13 at 19:12
  • 1
    @Elist Use this code and then make a `List` of `Game` objects and then call `Collections.shuffle(yourGameList);`, then it is random. – skiwi Dec 07 '13 at 19:13
  • @skiwi thanks for you edit, I intended the use of comparison with != since the object are supposed to be realy the same. Btw `equals` does the same check too before going any further :) – A4L Dec 07 '13 at 19:19
  • OK, thanks for introducing me to `Collections.shuffle()`, seems like that's what I was looking for... Please add it to your answer for sake of completeness. Anyway, I would still want to here if anyone knows anything about time complexity of `Collections.shuffle()`, and if there's a more efficient way (possibly iterations over shuffled lists) – Elist Dec 07 '13 at 19:20
  • @Elist for random order see skiwi's comment. – A4L Dec 07 '13 at 19:20
  • 1
    @skiwi here `teams.size() == 3` but the code runs in `O(n^2)`, so it is not `o(n^k)`. – Miserable Variable Dec 07 '13 at 19:20
  • @A4L Ah ok about the edit, I forgot to read your comment there. I still do not think you should present it as answer though when the question does not explicitely ask about reference comparison, it could confuse a lot of people. – skiwi Dec 07 '13 at 19:21
  • @A4L - oh, and `List matchUps = new ArrayList(teams.size()*2);` should be teams.size() factorial... – Elist Dec 07 '13 at 19:38
  • @Elist hehe you're almost right on that point, `teams.size() * teams.size() - teams.size()` is enough though :D – A4L Dec 07 '13 at 19:46