简体   繁体   English

Java生成随机播放器对

[英]Java generating random player pairs

my problem is generating random player pairs with equal number of games, but limiting number of games, so that all players don't have to play with each other. 我的问题是要生成具有相同游戏数量但限制游戏数量的随机玩家对,以便所有玩家不必彼此玩。

Think of it as a chess game, where random players are set to games, but every player don't have to play with all the players (it would just take too much time) but they all must have a equal number of games to competition be fair. 可以将其想象成一个国际象棋游戏,将随机的玩家设置为游戏,但是每个玩家不必与所有玩家一起玩(这将花费太多时间),但是他们都必须拥有相同数量的游戏才能参加比赛平心而论。

So far I generated a unique pairs for game, but all players must play everyone, that takes just too much time. 到目前为止,我已经为游戏生成了唯一的对,但是所有玩家都必须扮演所有人,这花费了太多时间。 I know that code isn't pretty but it must run once a month, to generate pairs: 我知道代码不是很漂亮,但必须每月运行一次才能生成对:

    @RequestMapping("/voistlus/{id}")
    public String newGame(Model model, @PathVariable Long id) {
    Stage stage = stageService.findOneById(id);
    if (gameService.findByStage(stage).isEmpty()) {
        List<Paar> paars = paarService.getAllPaar();
        List<Game> pairs = new ArrayList<Game>();
        for (Paar one : paars) {
            for (Paar two : paars) {
                if (!one.equals(two)) {
                    Game newPair = new Game();
                    newPair.setPaar1(one);
                    newPair.setPaar2(two);
                    if (!pairs.contains(newPair)) {
                        if (pairs.isEmpty()) {
                            pairs.add(newPair);
                            newPair.setStage(stage);
                            gameService.save(newPair);
                        } else {
                            boolean exists = false;
                            for (Game game : pairs) {
                                if (game.getPaar1().equals(two) && game.getPaar2().equals(one)) {
                                    exists = true;
                                }
                            }
                            if (!exists) {
                                pairs.add(newPair);
                                newPair.setStage(stage);
                                gameService.save(newPair);
                            }
                        }
                    }
                }
            }
        }
    }
    model.addAttribute("pairs", gameService.findByStage(stage));
    return "newGame";
}

Consider the graph where each player is a vertex, and an edge between players denotes a game between those players. 考虑该图,其中每个玩家是一个顶点,玩家之间的边缘表示这些玩家之间的游戏。 What we want to do is find cycles in this graph, where each cycle goes through all players, ie we want to find Hamiltonian cycles in this graph. 我们要做的是在此图中找到周期,每个周期都遍历所有参与者,即,我们要在此图中找到汉密尔顿周期。

In general, finding out if a graph has a Hamiltonian cycle is NP-complete. 通常,找出图是否具有哈密顿循环是NP完全的。 However, since the graph we consider in this problem is a complete graph (each vertex has an edge to each other vertex), this problem is quite easy. 但是,由于我们在此问题中考虑的图是一个完整的图(每个顶点彼此之间都有一条边),因此此问题非常容易。

We can do this with the following pseudocode 我们可以使用以下伪代码来做到这一点

Let V be the empty set
Let E be the empty set

Let init be a random vertex
Add init to V

While V does not contain all players
    Select a random vertex R that is not in V
    Add R to V
    Add the edge (init - R) to E
    Let init = R
End

E now contains the set of games to be played

By doing this multiple times, you will be able to generate multiple hamiltonian cycles, each cycle being a set of games where each player plays against exactly two other different players. 通过多次执行此操作,您将能够生成多个汉密尔顿循环,每个循环都是一组游戏,其中每个玩家与另外两个不同的玩家进行比赛。

This algorithm has one major disadvantage, which is that it allows the same game to occur multiple times. 该算法的一个主要缺点是,它允许同一游戏多次出现。 (It is possible that player 1 and player 2 have to play against each other more than once.) (玩家1和玩家2可能必须进行不止一次的对战。)

If we want to avoid this, we have to remove the cycle we found from the graph before searching the next cycle. 如果要避免这种情况,则必须在搜索下一个循环之前删除从图中找到的循环。 Doing this however makes determining if there is another cycle, and thus finding it, NP-complete again. 但是,这样做会确定是否还有另一个循环,从而找到它,再次使NP完成。

If you wish to solve this, a good starting point would be here and here . 如果您想解决这个问题, 这里这里都是一个很好的起点。

How about iterating over the number of games and each time picking random players? 遍历游戏数量并每次挑选随机玩家怎么样?

    int numberOfGames = 10;
    List<Paar> paars = paarService.getAllPaar();
    for (int game = 0; game < numberOfGames; game++) {
        // for each "game day", shuffle the list of players
        Collections.shuffle(paars);
        for (int playerIndex = 0; playerIndex < paars.size(); playerIndex+=2) {
            Game newPair = new Game();
            newPair.setStage(stage);
            newPair.setPaar1(paars.get(playerIndex));
            newPair.setPaar2(paars.get(playerIndex+1));
            gameService.save(newPair);
        }
    }

Downside is that you can't avoid the same player pair playing multiple times against each other; 缺点是您不能避免同一对玩家多次对战。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM