繁体   English   中英

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

[英]How can I create a random event that will not repeat results?

我正在尝试使用Xcode和C ++创建一个团队生成应用程序,该应用程序将生成三个或四个团队。 目前,我能够输入名称并使用数组随机生成团队:

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

    int index=rand() % count;


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

从这个数组中,我将根据数组的顺序分配三人一组。 因此,数组[1],[2]和[3]组成了团队#1。 数组[4],[5]和[6]组成了小组#2,因此排名第四。

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

例如,如果人#1,#2和#3都放在同一个团队中,则下次我生成团队时,人#1,#2和#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]);
}

然后,您便拥有了全部东西。

对不起,部分解决方案。

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

您还可以进入部分放置的状态,那里没有解决方案,仅涉及向团队中添加球员。 这意味着您不能随便挑剔并拒绝加入包含您之前所在成员的团队。

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

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

如果您想遍历所有可能性,还可以使用std::next_permutation() 但是,除非团队成员人数少,否则将有大量可能的配置。 您可以略微减少组合的数量,因为团队中的玩家可以是任意顺序。

这似乎是回溯的明显案例。 不确定这是否是最有效的方法,但是它比随机算法简单,而且肯定比随机算法要好。

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

第二个数据结构只是std::vector<bool> assigned的bod 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

暂无
暂无

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

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