首先,这个问题是扯出 问题。我这么做是因为我认为,这部分是比一副部长的问题。如果冒犯了,请原谅我。

假设你有一个算法产生的随机性。现在你如何测试?或者更直接假定你有了一种算法,打乱一副纸牌,你怎么测试,这是一个完全随机的算法?

添加一些理论上的问题 一副牌可打乱52!(52因子)不同的方式。采取一副扑克牌,洗手写下了所有的卡片。什么是概率,你将得到完全洗牌?回答:1/52!.

什么样的机会有你,之后洗牌,将A、K、Q、J...每个适合在一个顺序?回答1/52!

所以,只要洗一次,看看结果会给你绝对没有任何信息对你洗牌的算法的随机性。两次,你有更多的信息,三个甚至更...

怎么会你的黑盒子测试混算法进行的随机性?

有帮助吗?

解决方案

统计数据。事实上的标准进行测试RNGs是的 顽固的套房 (原本可以在 http://stat.fsu.edu/pub/diehard).或者, Ent程序 提供测试简单的解释,但不全面的。

如洗牌的算法,使用众所周知的算法,例如 Fisher-耶茨 (a。k.一个"Knuth洗牌").混乱将是均匀地随机的,所以只要基础丽贝卡是均匀地随机的。如果您使用的是爪哇,这种算法可用于标准库(见 集合。洗牌).

它可能不要紧,对于大多数应用程序,但要注意,最RNGs没有提供足够的自由度,以产生每一个可能的置换的52张牌(解释 在这里,).

其他提示

这里有一个简单检查即可以执行。它使用所产生的随机数来估计。这不证明的随机性,但贫穷RNGs通常不这样做,它(他们将返回的东西喜欢2.5或3.8而~3.14).

理想情况下,这将是一个测试,你会检查的随机性。

别的东西,你可以检查是的 标准偏差 输出。预期的标准偏差对于一个均匀分布的人口的数值范围在0..n办法n/sqrt(第12条)。

/**
 * This is a rudimentary check to ensure that the output of a given RNG
 * is approximately uniformly distributed.  If the RNG output is not
 * uniformly distributed, this method will return a poor estimate for the
 * value of pi.
 * @param rng The RNG to test.
 * @param iterations The number of random points to generate for use in the
 * calculation.  This value needs to be sufficiently large in order to
 * produce a reasonably accurate result (assuming the RNG is uniform).
 * Less than 10,000 is not particularly useful.  100,000 should be sufficient.
 * @return An approximation of pi generated using the provided RNG.
 */
public static double calculateMonteCarloValueForPi(Random rng,
                                                   int iterations)
{
    // Assumes a quadrant of a circle of radius 1, bounded by a box with
    // sides of length 1.  The area of the square is therefore 1 square unit
    // and the area of the quadrant is (pi * r^2) / 4.
    int totalInsideQuadrant = 0;
    // Generate the specified number of random points and count how many fall
    // within the quadrant and how many do not.  We expect the number of points
    // in the quadrant (expressed as a fraction of the total number of points)
    // to be pi/4.  Therefore pi = 4 * ratio.
    for (int i = 0; i < iterations; i++)
    {
        double x = rng.nextDouble();
        double y = rng.nextDouble();
        if (isInQuadrant(x, y))
        {
            ++totalInsideQuadrant;
        }
    }
    // From these figures we can deduce an approximate value for Pi.
    return 4 * ((double) totalInsideQuadrant / iterations);
}

/**
 * Uses Pythagoras' theorem to determine whether the specified coordinates
 * fall within the area of the quadrant of a circle of radius 1 that is
 * centered on the origin.
 * @param x The x-coordinate of the point (must be between 0 and 1).
 * @param y The y-coordinate of the point (must be between 0 and 1).
 * @return True if the point is within the quadrant, false otherwise.
 */
private static boolean isInQuadrant(double x, double y)
{
    double distance = Math.sqrt((x * x) + (y * y));
    return distance <= 1;
}

第一,这是不可能肯定知道如果某些有限的输出"真正的随机",因为正如你所指出的, 任何输出是可能的.

有什么可以做的,是采取一种序列的产出和检查各种测量的这个序列针对什么可能性更大。你可以推导出排序的信心,这是你的生成的算法是做一个好工作。

例如,你可以检查出10个不同的洗牌.分配数0到51每个卡,并采取平均的卡在位置6跨洗牌.该收敛平均为25.5,所以你会惊讶地看到一个价值1在这里。你可以使用的中央限定理获得的估计如何有可能每平均是为了给定的位置。

但是,我们不应该停在这里!因为这个算法可能会被愚弄了一个系统,只有替补人员之间的两洗牌,目的是得到准确的平均25.5在每个位置。我们怎么可以做的更好?

我们期望的均匀分布(相等的可能性对于任何给定的卡)在每个位置,跨越不同的洗牌.所以其中的10慢腾腾,我们可以尝试验,选择的看起来均匀的。' 这是基本上只是一个缩减版本原来的问题。你可以检查的标准偏差的看起来合理,分是合理的,并最大价值。你也可以检查,其他价值观,例如最近的两张卡(由我们分配数量),也有意义。

但是,我们也不能只是增加各种测量这样循环往复,因为,给予足够的统计数据,任何特别的洗牌将出现极不可能因为某些原因(例如这是一个非常少的洗牌在哪卡X、Y、Z中出现的顺序)。所以,最大的问题是:这是正确的测量走?在这里,我不得不承认,我不知道的最好的答案。但是,如果你有一定的应用在头脑,您可以选择一套很好的性能/测量测试、和工作与那些--这似乎是种密码破译处理的事情。

有很多理论上测试,随机性。对于一个非常简单的测试在一个洗牌算法你可以做很多的洗牌然后再运行卡方测试的概率各卡现在的任何立场是均匀的。但是,这并不测试,连续的卡不相关,所以你也会想要做测试。

2卷Knuth的技术的计算机编程给出了一些测试可能用在第3.3.2(经验性试验)和3.3.4(频谱测试)和背后的理论。

洗牌很多,然后记录结果(如果我读到这正确的).我记得看到比较的"随机数发生器".他们只是测试它,然后的图表的结果。

如果这是真正随机的图将大多。

唯一的方法来测试,随机性是写一个程序,试图建立一个预测模型的数据正在进行测试,然后使用该模型来预测未来数据,然后表示,不确定性,或熵,其预测往往最大(即均匀分布)。当然,你永远是不确定是否或不是你的型捕获的所有必要的上下文;给出一个模型,它就会总是有可能建立第二个模型,产生非随机数据,看起来随机的第一个。但只要你接受的轨道冥王星已经微不足道的影响结果的洗牌算法,然后你应该能够满足自己,其结果是可以接受的。

当然,如果你做这,你还不如用你的模型 generatively, ,实际上创建的数据。如果你做这,然后你回到广场之一。

我不充分以下你的问题。你说

假设你有一个算法产生的随机性。现在你如何测试?

你什么意思?如果你是在假设你可以产生随意性,有没有必要进行测试。

一旦你有了一个良好的随机数发生器,创造一个随机排列易(例如叫你的卡,第1-52.产生52随机数字分配各一个来卡在了,然后排序根据你的52偶合).你不会摧毁的随机性的,你好,丽贝卡通过产生您的置换。

困难的问题是,是否你可以信任你的丽贝卡. 这里的 一个样本链接到人讨论这一问题在一个特定的上下文。

测试52!可能性当然是不可能的。而是,试试你的洗牌在较小的数字卡片,就像3、5、10.然后你就可以测试了数十亿的洗牌和使用的直方图和卡方统计试验证明,每个置换过来的",甚至"的次数。

没有代码,因此为止,因此我复制贴的试验部分 我的回答 到原来的问题。

  // ...
  int main() {
    typedef std::map<std::pair<size_t, Deck::value_type>, size_t> Map;
    Map freqs;    
    Deck d;
    const size_t ntests = 100000;

    // compute frequencies of events: card at position
    for (size_t i = 0; i < ntests; ++i) {
      d.shuffle();
      size_t pos = 0;
      for(Deck::const_iterator j = d.begin(); j != d.end(); ++j, ++pos) 
        ++freqs[std::make_pair(pos, *j)]; 
    }

    // if Deck.shuffle() is correct then all frequencies must be similar
    for (Map::const_iterator j = freqs.begin(); j != freqs.end(); ++j)
      std::cout << "pos=" << j->first.first << " card=" << j->first.second 
                << " freq=" << j->second << std::endl;    
  }

这种代码不试验的随机性的基础伪随机数发生器。测试养恤金条例》的随机性是一个整体的分支的科学。

对于一个快速测试,你可以随时尽量压缩。一旦它不压缩,然后你可以移动到其它的测试。

我已经试过dieharder但它拒绝工作为洗牌。所有的测试失败。这也是真的很乏味,它不会让你指定的数值范围你想或者类似的东西。

琢磨我自己,我会做的就是这样的:

设置(伪代码)

// A card has a Number 0-51 and a position 0-51
int[][] StatMatrix = new int[52][52]; // Assume all are set to 0 as starting values
ShuffleCards();
ForEach (card in Cards) {
   StatMatrix[Card.Position][Card.Number]++;
}

这为我们提供了一个矩阵52x52指示有多少次一个卡已经结束了在一定的位置。重复这是一个大型的次数(我会开始有1000,但人们的更好的统计数据比我可以得到更好的数量)。

分析的矩阵

如果我们有完美的随机性和执行随机的一个无限的次数,然后为每张卡,并为每个位置的次数卡结束在那个位置是相同的任何其他的卡片。说同样的事情在不同的方式:

statMatrix[position][card] / numberOfShuffle = 1/52.

所以我计算如何远离这一数字,我们是。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top