洗牌很好的RNG

时间:2011-09-21 13:50:33

标签: c++ random

现在我正在使用Mersenne Twister RNG并执行Fisher-Yates shuffle算法100次:

    std::vector<Card> shufCards;
    for(int i = 0; i < 4; ++i)
    {
        for(int j = 0; j < 13; ++j)
        {

            shufCards.push_back(Card((Card::SuitEnum)i,(Card::RankEnum)j));
        }
    }
    for(int r = 0; r < 100; ++r)
    for(int i = shufCards.size() - 1; i >= 1; i--)
    {
        int j = m_randomGenerator.genrand_int31() % (i + 1);
        std::swap(shufCards[i],shufCards[j]);
    }

    std::vector<Card> cards;
    for(int i = 0; i < zeroBasedCut; ++i)
    {
        cards.push_back(shufCards[i]);
    }

    for(int i = zeroBasedCut; i < 52; ++i)
    {
        cards.push_back(shufCards[i]);
    }


    return cards;

但感觉就像每件西装的卡片数量有关并且有些可预测。

,这种情况不太可能只有1只心脏和5只黑桃的13张牌。

我可以使用什么更好的RNG?

由于

2 个答案:

答案 0 :(得分:8)

我们对随机性的看法非常糟糕。如果你怀疑你的例程在某种程度上有所偏差,我建议你使用你的例程进行大量的随机试验,然后查看各种手部分布的实现概率,并将它们与理论上的预期进行比较。 / p>

除此之外,我还有一些观察结果:

  1. 为什么要多次洗牌?一遍应该做得很好。
  2. zeroBasedCut的目的是什么? Fisher-Yates没有实现什么目标?
  3. 为什么不使用std::random_shuffle而不是自己的例程?

答案 1 :(得分:2)

良好随机性有三个部分:

  1. 种子熵的良好来源。
  2. 一个好的PRNG。
  3. 使用随机性的好算法。
  4. 对于纸牌游戏,Mersenne Twister和Fisher-Yates shuffle都很好。如果你得到可重复的结果,我怀疑你的熵来源很差。你在播种RNG吗?