一个好的随机数发生器的想法是什么?

Vla*_*mir 0 c++ random algorithm numbers

我正在为纸牌游戏写一个程序.可以有几个游戏玩家(比如,从2到7).一副牌组由54张牌组成.我需要随机向玩家分发/发牌.

我们可以将54张牌的牌组视为54个元素的char数组.让我们假设在某个游戏中,每个玩家必须获得6张牌.玩家的数量是2.因此,有必要生成两个阵列,每个阵列由从54个元素的"大"数组中选择的6个元素组成.而且,在这两个生成的数组中,不应该有共享/重复元素.

我尝试了一种递归算法来获得从0到(m-1)的m个唯一随机数序列.

X(n + 1)=(a*X(n)+ c)mod m

您需要设置参数:

  • m - 模块,m> 0
  • a - 因子,0 <= a <m
  • c - 增量,0 <= c <m
  • X(0) - 初始值,0 <= X(0)<m
  • 数字cm必须是互质的.
  • 对于作为m的除数的每个素数p,(a-1)可被p整除
  • 如果m可被4整除,则(a - 1)必须可被4整除.

这是此算法的代码.如您所见,参数a,c,m和X(0)满足上述条件.

int a = 13,
    c = 11,
    m = 54, // because the total number of cards is 54
    x0 = 1;

int x[100];
x[0] = x0;
cout << x[0] << "  ";

for (int i = 1; i < m; i++)
{
    x[i] = (a * x[i - 1] + c) % m;
    cout << x[i] << "  ";
}
Run Code Online (Sandbox Code Playgroud)

其结果是:1 24 53 52 39 32 49 0 11 46 15 44 43 30 23 40 45 2 37 6 35 34 21 14 31 36 47 28 51 26 25 12 5 22 27 38 19 42 17 16 3 50 13 18 29 10 33 8 7 48 41 4 9 20.你认为它是随机的吗?

你能对这个算法说些什么?一般来说,每个玩家随机分配卡片的想法应该是什么?

你看,如果我将这个算法集成到我的程序中,它将处理每次启动程序时上面显示的相同序列的卡(因为参数不会改变).所以我需要在我的程序启动之间更改a,m,c和X(0).然后我会遇到另一个问题:如何自动设置这些参数(也是随机设置),以便它们满足必要条件(参见上面的项目符号列表).

Mic*_*sen 5

在我看来,你正在制造一个不必要的复杂系统.

一种更简单的方法是创建一个包含所有元素的数组,随机化,然后一次删除一个元素.

一种简单而有效的改组方式是使用Fisher-Yates shuffle:

//Initialize an array/vector/etc. with all the possible values
for (int i = NUMBER_OF_ELEMENTS-1; i >= 0; i--)
{
  //Pick a random integer j between 0 and i (inclusive)
  //Swap elements i and j
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以遍历洗牌数组,每次需要新卡时选择下一个元素.

int pos = 0; //The position of the next card in the deck
for (int i = 0; i < 6; i++)
{
  for (int j = 0; j < NUMBER_OF_PLAYERS; j++)
  {
    player[j].addCard(deck[pos++])
  }
}
Run Code Online (Sandbox Code Playgroud)

理想情况下,您可能希望将其中的一部分包装到类中,但为了简洁起见,我将其留下了.

  • C++已经有了`std :: random_shuffle`和`std :: shuffle`. (2认同)