如何测试洗牌程序

关于洗牌程序的文章 ,之前已经写过一篇,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

posted @   caochao88  阅读(706)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
点击右上角即可分享
微信分享提示