这会输出一次随机洗牌一百万次吗? rand()c ++

时间:2012-12-24 05:47:53

标签: random shuffle

我正在尝试运行一百万次卡片游戏模拟以返回百分比“赌场边缘”。

我对rand()函数的理解还不够清楚,每次都会产生一个新的shuffle,或者它是否有限制。换句话说,在百万游戏的某个时刻,是否会出现相同的洗牌模式?

  srand(time(NULL));

for (int games=0;games<iGames;games++){

                  ///shuffle///
for (int i=0; i<(iUserDeckSize-1); i++) {
    int r = i + (rand() % (iUserDeckSize-i)); // Random remaining position.
    card temp = cards[i]; cards[i] = cards[r]; cards[r] = temp;
}

// rest of card game code goes here
}

2 个答案:

答案 0 :(得分:1)

我认为它是特定于实现的,请参见此处What common algorithms are used for C's rand()?。但是如果实际的实现开始快速重复,我会感到震惊,我原本以为你至少会进入int32允许的数十亿。

答案 1 :(得分:0)

没有2个理由(一个你想到的,一个不那么明显)。

您使用的算法是错误的。抛开令人担忧的-1(最后一个元素根本不会被洗牌)你有n^n个可能的运行(接收到的随机数的空间),而n!可能有洗牌。一般来说,n!不是n^n的因子,因此你有偏见的输出(即某些结果会比其他结果更频繁地发生)。我建议您实施Knuth-Tares shuffle或使用已经实施的算法,例如来自random_shuffle的{​​{1}}。

那就是说 - 你需要拥有至少有<algorithm>个状态的PRNG。根据甲板大小,rand()可能不够 - 它通常有~48位,而标准52卡甲板有~225位状态(n!) - 换句话说,没有机会击中某些序列(这可能不是问题,但更好的PRNG的开销可以忽略不计)。我会看boost random,因为它有几个很好的PRNG实现,并且至少有一个可能足够好(例如,对于52卡示例mt11213b)。