生活资讯
(随机算法)
2024-12-16 15:22  浏览:116

我希望本文有助于你了解测试软件是一件很重要也是一件不简单的事。

我们有一个程序,叫ShuffleArray(),是用来洗牌的,我见过N多千变万化的ShuffleArray(),但是似乎从来没人去想过怎么去测试这个算法。所以,我在面试中我经常会问应聘者如何测试ShuffleArray(),没想到这个问题居然难倒了很多有多年编程经验的人。对于这类的问题,其实,测试程序可能比算法更难写,代码更多。而这个问题正好可以加强一下我在《我们需要专职的QA吗?》中我所推崇的——开发人员更适合做测试的观点。

我们先来看几个算法(第一个用递归二分随机抽牌,第二个比较偷机取巧,第三个比较通俗易懂

递归二分随机抽牌

有一次是有一个朋友做了一个网页版的扑克游戏,他用到的算法就是想模拟平时我们玩牌时用手洗牌的方式,是用递归+二分法,我说这个程序恐怕不对吧。他觉得挺对的,说测试了没有问题。他的程序大致如下(原来的是用Javascript写的,我在这里凭记忆用C复现一下):

 

随便测试几次,还真像那么回事:

快排Hack法

让我们再看一个hack 快排的洗牌程序(只看算法,省去别的代码):

运行个几次,感觉得还像那么回事:

看不出有什么破绽。

大多数人的实现

下面这个算法是大多数人的实现,就是for循环一次,然后随机交换两个数

跑起来也还不错,洗得挺好的。

但是上述三个算法哪个的效果更好?好像都是对的。一般的QA或是程序员很有可能就这样把这个功能Pass了。但是事情并没有那么简单……

如何测试

在做测试之前,我们还需要了解一下一个基本知识——PC机上是做不出真随机数的,只能做出伪随机数。真随机数需要硬件支持。但是不是这样我们就无法测试了呢,不是的。我们依然可以测试。

我们知道,洗牌洗得好不好,主要是看是不是够随机。那么如何测试随机性呢?

试想,我们有个随机函数rand()返回1到10中的一个数,如果够随机的话,每个数返回的概率都应该是一样的,也就是说每个数都应该有10分之1的概率会被返回。

一到概率问题,我们只有一个方法来做测试,那就是用统计的方式。也就是说,你调用rand()函数100次,其中,每个数出现的次数大约都在10次左右。(注意:我用了左右,这说明概率并不是很准确的)不应该有一个数出现了15次以上,另一个在5次以下,要是这样的话,这个函数就是错的。

举一反三,测试洗牌程序也一样,需要通过概率的方式来做统计,是不是每张牌出现在第一个位置的次数都是差不多的。

于是,这样一来上面的程序就可以很容易做测试了。

下面是测试结果(测试样本1000次——列是每个位置出现的次数,行是各个字符的统计,出现概率应该是1/10,也就是100次):

递归随机抽牌的方法

很明显,这个洗牌程序太有问题。算法是错的!

快排Hack法

看看对角线(从左上到右下)上的数据,很离谱!所以,这个算法也是错的。

大多数人的算法

我们再来看看大多数人的算法。还是对角线上的数据有问题,所以,还是错的。

正确的算法

下面,我们来看看性能高且正确的算法—— Fisher_Yates算法

这个算法不难理解,看看测试效果(效果明显比前面的要好):

但是我们可以看到还是不完美。因为我们使用的rand()是伪随机数,不过已经很不错的。最大的误差在20%左右。

我们再来看看洗牌100万次的统计值,你会看到误差在6%以内了。这个对于伪随机数生成的程序已经很不错了。

如何写测试案例

测试程序其实很容易写了。就是,设置一个样本大小,做一下统计,然后计算一下误差值是否在可以容忍的范围内。比如:

  • 样本:100万次
  • 最大误差:10%以内
  • 平均误差:5%以内 (或者:90%以上的误差要小于5%)

注意

其实,以上的测试只是测试了牌在各个位置的概率。这个还不足够好。因为还可能会现在有Patten的情况。如:每次洗牌出来的都是一个循环顺序数组。这完全可以满足我上面的测试条件。但是那明显是错的。所以,还需要统计每种排列的出现的次数,看看是不是均匀。但是,如果这些排列又是以某种规律出现的呢?看来,这没完没了了。

测试的确是一个很重要,并不简单的事情。谢谢所有参与讨论的人。

附录

之前忘贴了一个模拟我们玩牌洗牌的算法,现补充如下:

我们来看看测试结果:(10万次)效果更好一些,误差在2%以内了。

(全文完)

    以上就是本篇文章【(随机算法)】的全部内容了,欢迎阅览 ! 文章地址:http://sjzytwl.xhstdz.com/xwnews/512.html 
     栏目首页      相关文章      动态      同类文章      热门文章      网站地图      返回首页 物流园资讯移动站 http://mip.xhstdz.com/ , 查看更多   
最新文章
教你彻底关闭手机自动更新,老手机不再卡顿还可以继续用几年手机系统更新怎么关闭「教你彻底关闭手机自动更新,老手机不再卡顿还可以继续用几年」
当我们购买一部新手机时,第一时间关闭系统更新是非常重要的。你们知道为什么我们经常更换手机吗?不正是因为手机变得卡顿和不流
电信固话怎么设置呼叫转移座机转接到手机怎么设置「电信固话怎么设置呼叫转移」
在现代通信中,呼叫转移功能为用户提供了极大的便利,尤其是在无法接听电话或需要临时将电话转接到其他号码时。对于电信固话用户
从“出新必换”到“多年不换”,消费者为啥不爱换手机了?手机几年换一次比较好「从“出新必换”到“多年不换”,消费者为啥不爱换手机了?」
你有多久没换手机了?不少消费者反馈,自己已经一两年或更长时间没有购买新手机或新平板电脑了。从“出新必换”到“多年不换”,
求小明正确的四位手机密码手机密码破解「求小明正确的四位手机密码」
小学生题目:小明五次输入四位数的手机密码均错误,但是每次输入的密码中都有两位数字正确,且输入的数字的位
奥尼尔谈GOAT人选:NBA仅4人够格
关于谁才是NBA的GOAT,每个人心中都会有自己的看法,毕竟大家看比赛的角度不同,对于球星成色的判断也就不同。近日,奥尼尔就谈
新就业形态下,灵活就业人员权益如何保障?
原标题:新就业形态下,灵活就业人员权益如何保障?(主题)专家:多方协同推动劳动者权益保障与企业可持续发展(副题)中国妇女
5G麒麟芯+卫星通信!华为20多款中端机已备案,继续发力高性能手机「5G麒麟芯+卫星通信!华为20多款中端机已备案,继续发力」
近日,有消息称华为将不仅在高端市场回归,还将回归中端市场,将麒麟9000s芯片下放到中端手机中。同时,华为还计划在中端手机中
买台手机好过年 没选新出的S16 Pro 却买了上代15 Pro新出的手机「买台手机好过年 没选新出的S16 Pro 却买了上代15 Pro」
购买小米12 Pro翻车后,眼看离春节就几天,还是要在过年前满足自己买过年的愿望。只考虑了OPPO和VIVO的产品后,放弃了OPPO的Reno
iPhone游戏必备神器、精准识别那个老六。雷蛇手机「iPhone游戏必备神器、精准识别那个老六。」
相信很多用iPhone玩游戏的值友们都遇到过降频的问题,尤其13PM,虽然支持120hz但是只要你敢开,十分钟内必让你的屏幕黑下来,感
割裂的杭州楼市:手握千万资金抢不到房,刚需盘降价40万无人问津
“ 杭州一季度的楼市表现,如同一面多棱镜,映照出土地市场的狂热、开发商的野心、购房者的焦虑,也暴露出城市发展的不均衡。中