zoukankan      html  css  js  c++  java
  • 如何测试洗牌程序

    关于洗牌程序的文章 ,之前已经写过一篇,http://www.cnblogs.com/tudas/p/3-shuffle-algorithm.html ,因为上次被nie大神们重新问到且没有正确回答上来,所以有必要在研究一下。

    这次来说说n张牌的洗牌程序如何测试。众所周知,洗牌即得到n的一个全排列结果(1/n!),因此每张牌在每个位置出现的概率是1/n。

    一个洗牌程序的功能是,对于长度为n的两两不同的数组,输出的任何一个排列的概率相等,也就是1/n!。可以验证,Fisher-Yates算法是可以保证这一点的。

    贴上我的测试代码:

    import random
    
    #测试次数
    test_count = 10000
    
    #记录字典
    counter = {}
    
    #测试集合
    char_array = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' ]
    
    #fisher_yates洗牌算法
    def fisher_yates_shuffle( array ):
        array_len = len( array )
        for i in range( array_len - 1, 0, -1 ):
            r = random.randrange( 0, i)
            array[ i ], array[ r ] = array[ r ], array[ i ]
        return array
    
    #记录每张牌在每个位置出现的次数
    def count( array, counter ):
        for i in range( len( char_array ) ):
            char = array[ i ]
            pos = i + 1
            if not counter.get( char ):
                counter[ char ] = {}
            if not counter[ char ].get( pos ):
                counter[ char ][ pos ] = 0
            counter[ char ][ pos ] += 1
    
    #测试test_count次
    for i in range( test_count ):
        shuffled = fisher_yates_shuffle( char_array )
        count( shuffled, counter )
    
    #打印结果
    for key in sorted( counter.keys() ):
        print( key, counter[ key ] )

    测试10000次结果:可以看到, a~b每张牌出现位置1~10的概率大致相当.

    测试1000000次结果:数据量越大, 牌的位置越趋于平均分布.

    参见:

    http://blog.codingnow.com/2007/09/shuffle.html

    http://coolshell.cn/articles/8593.html

  • 相关阅读:
    Linux内存管理2---段机制
    XCOJ 1102 (树形DP+背包)
    ZOJ 3805 (树形DP)
    Ural 1018 (树形DP+背包+优化)
    POJ 2342 (树形DP)
    HDU 2612 (BFS搜索+多终点)
    POJ 1947 (树形DP+背包)
    HDU 1561 (树形DP+背包)
    HDU 1045 (DFS搜索)
    HDU 5067 (状态压缩DP+TSP)
  • 原文地址:https://www.cnblogs.com/tudas/p/a_method_to_test_fisher_yates_shuffle_algorithm.html
Copyright © 2011-2022 走看看