如何随机分散ArrayList?

时间:2016-10-20 21:31:46

标签: java algorithm

我正在尝试为锦标赛制定游戏计划的应用程序。

我有一个方法:

public List<Match> creerMatchsTousContreTous(List<Equipe> lEquipe) {
        List<Match> lMatch = new ArrayList<>();
        for (int i = 0; i < lEquipe.size(); i++) {
            for (int j = i + 1; j < lEquipe.size(); j++) {
                Match match = new Match();
                match.setEquA(lEquipe.get(i));
                match.setEquB(lEquipe.get(j));
                lMatch.add(match);
            }
        }
        return lMatch;
    }

此方法收到了一个团队列表。每个人都必须互相玩耍。这将返回一个播放列表(匹配)。

我现在要随机播放这些剧本。我需要一个玩第一个Play的A队不能玩下一个。还有更多。

我用:

Collections.shuffle(lMatch);

但是那个ramdom是戏剧列表,而且tema可能连续两次播放。

我怎样才能实现这一目标? 谢谢 最诚挚的问候

编辑:

实施例

该方法返回游戏列表:

  1. 第1组:第2组

  2. 第2组:第3组

  3. 第1组:第3组

  4. 第4组:第3组

  5. 第2组:第4组

  6. 第4组:第3组

  7. creerMatchsTousContreTous()在此示例中返回一个包含6个值的列表。但是在这里,例如,在第一场比赛中,TEAM 2正在比赛,在第二场比赛中他也在比赛,但这绝对不是。

2 个答案:

答案 0 :(得分:0)

我建议在Team类中添加一个布尔变量,例如justPlayed或hasPlayed。该变量将跟踪特定团队是否刚刚参与游戏。

Collections.shuffle(lMatch); // get two random teams using shuffle
while(Match.Team1.getHasPlayed() == True or Match.Team2.getHasPlayed() == True){
    Collections.shuffle(lMatch); // try to find different teams
}

lMatch.play(); // you've found two teams, so now you can call your play method

for(Team t:lEquipe){             // go through the list of teams and
    t.setHasPlayed(false);       // reset the rest each team's boolean
}
Match.Team1.setHasPlayed(true);
Match.Team2.setHasPlayed(true); // set the boolean to true at the end of the turn
//

这显然是伪代码,因为我不知道您对Match和Team的实现。不过,请考虑使用布尔实例字段并检查它是否在上一轮中被修改过。

答案 1 :(得分:0)

下面的一个是递归方法。我认为它可以以比@Sonedring建议的更快的方式提供解决方案,因为在每次随机化之后都会应用约束。

对于少于4支球队的角球情况,这也更安全。在角落的情况下,你将找不到解决方案而且你不会无限循环。

希望这有帮助。

public static void randomize(List<Match> matches) {
    List<Match> randomizedList = new ArrayList<>();
    int numberOfAttempts = 256;

    // tmpSubList is a temporary list that contains all matches
    // (excluding unwanted) after n-th iteration (randomization).
    List<Match> tmpSubList = new ArrayList<Match>(matches);
    while (matches.size() > 0) {

        // if tmpSubList contains - it means there is no match that can be added.
        // Need to restart randomization algorithm.
        if (tmpSubList.size() == 0) {
            System.out.println("Restarting algorithm.");

            if (--numberOfAttempts == 0) {
                throw new ArithmeticException("Could not find solution.");
            }
            // Need to restart:
            matches.addAll(randomizedList);
            tmpSubList.addAll(randomizedList);
            randomizedList.clear();
        }

        int randomIndex = (int) (tmpSubList.size() * Math.random());

        Match match = tmpSubList.remove(randomIndex);
        matches.remove(match); // remove also from the main list;
        randomizedList.add(match);

        Equipe lastTeam1 = match.getEquA();
        Equipe lastTeam2 = match.getEquB();

        tmpSubList.clear();
        matches.stream()
            .filter( x -> !x.getEquA().equals(lastTeam1) && !x.getEquB().equals(lastTeam1) )
            .filter( x -> !x.getEquA().equals(lastTeam2) && !x.getEquB().equals(lastTeam2) )
            .forEach( x -> tmpSubList.add(x));
    }
    matches.addAll(randomizedList);
}