如何创建不会重复结果的随机事件?

时间:2015-11-17 00:50:18

标签: c++ xcode random

我正在努力让一个团队使用Xcode和C ++生成应用程序,这将生成三人团队或四人团队。目前,我可以输入名称并使用数组随机生成团队:

    for (j=1;j < count; j++) {

    int index=rand() % count;


    NSString *temp = Array[j];
    Array[j]=Array[index];
    Array[index]=temp;

从这个数组中,我根据数组的顺序分配三个团队。所以Array [1],[2]和[3]组成了团队#1。数组[4],[5]和[6]组成第2组,第四组。

从这里开始,我想使用与以前相同的名称池随机生成新的团队,但不要让人们与他们已经在团队中的人员组成团队。

例如,如果#1,#2和#3人都被放置在同一个团队中,那么下次我创建团队时,#1,#2和#3人都会在不同的团队中。

这是我现在的主要关注点。最终,我希望能够调整程序以允许重复的团队成员,因为非重复的团队成员在后来的团队世代中变得不可能。

3 个答案:

答案 0 :(得分:1)

我不确定我对4队或3队的队伍是否正确,但是,为了避免数学上的复杂性(检查越来越多的指数可能性);我建议您生成每个可能的团队并随机选择团队,而不是尝试随机生成团队并按顺序进行。

我错过了算法的一部分,所以我会在这里为3名玩家组成一个简化版本。

typedef std::tuple<Player,Player,Player> team;
std::vector<Team> definitive_teams, list_of_teams;

//that's the part where I miss the algorithm,
//where you create EACH possible team
//and store them
list_of_teams.reserve(Number_of_team_max); //you have to figure that too
list_of_teams.push_back(make_tuple(arg1,arg2,arg3));
//then simply :

definitive_teams.resize(list_of_teams.size());

size_t index;
std::srand(std::time(0));
for (size_t i {0};i < definitive_teams.size();++i)
{
    index= std::rand()%(list_of_teams.size() - i);
    definitive_teams[i] = list_of_teams[index];
    if (index != list_of_teams.size() - i)
        swap(list_of_teams[index],list_of_teams[list_of_teams.size() - i]);
}

然后你就完成了所有事情。

对于部分解决方案感到抱歉。

答案 1 :(得分:1)

你需要在这里小心。在某些情况下,您无法使用这些规则生成团队。例如,如果您将6个人分成两个3人团队,那么第二组团队将无法生成。

你也可以进入一个部分放置的状态,其中没有解决方案只涉及将球员添加到球队。这意味着您不能随意挑选并拒绝将其放置到包含您之前与之成员的团队中。

我认为最简单的解决方案是改变整个状态,直到它正确为止。

为此,您可以使用std::random_shuffle()对数组进行随机播放,直到找到有效的配置。请注意,如果没有有效的解决方案,这将永远搜索,如果只有很小一部分配置实际有效,则可能需要很长时间。

如果你想迭代各种可能性,还有std::next_permutation()。但是,除非团队成员数量较少,否则将会有大量可能的配置。您可以稍微减少组合的数量,因为团队中的玩家可以按任何顺序。

答案 2 :(得分:1)

这看起来像回溯的明显案例。不确定它是否是最有效的方法,但它比随机算法简单且肯定更好。

所需的第一个数据结构是一系列团队成员,他们都在同一个团队中。对于N个人来说,这是一组(N N-1)/ 2套bool。使用完整的N N阵列可能更容易。 std::vector<std::vector<bool>> conflicts

第二个数据结构只是一个bool std::vector<bool> assigned数组,表示当前一轮已经将哪些人分配给了一个团队。

第三个数据结构是实际的团队分配,由人和团队密切。在幕后,这最好由两个数组实现,其中一个是人数是索引,另一个是团队编号是索引。

该算法的工作原理如下

In each round:
  Set all teams to empty
  Find first non-assigned person in `assigned`
    Add person to first team that has <4 members and no conflicts.
    If not team found, backtrack:
      Undo the assignment of the _previous_ person
      Assign person to the next possible team
    When team found: 
       Update `assigned`
       Update team membership
  Until all people assigned to teams
  Update `conflicts` with team membership from this round
Continue with next round