辛苦工做一年,大大小小的公司或单位组织都会搞一个年会。年会少不了抽奖,每一个人都期待本身是抽中一等奖,然而现实是残酷的,我今年也没抽中,毛都没中一根。这是为何呢?咱们就来聊聊抽奖算法的那些事。 年会抽奖,按照形式,能够分为实物抓阄和程序随机算法。javascript
这个你们都知道,搞一个抽奖箱,每一个人入场的时候把本身的名字写在纸条上,折起来,投入箱子里就能够。接下来你的命运就掌握在上台抽奖的领导大佬们的手上了。抽奖一定是先从最差的末等奖开始抽,有些公司或单位组织是5等奖,有些直接三等奖,没办法,得留意预算。这种抽奖的状况,若是主持人不摇一摇,而且排除领导同志喜欢海底捞的癖好,那么越靠后投进箱子的朋友越容易被抽中。但是也别靠太后。我知道大家又想被抽中,又不想被早点抽中。若是三等奖就是一张电影券,你若被抽中,那还不如拿个杨光普照。反过来想一想,若是一家公司三等奖是一张电影票,你等到一等奖,也不会有什么期待,或许是一把牙刷雷死你不偿命。java
另一种形式,那就是程序抓阄了。程序抓阄,就是经过编写一个电子抽奖程序,实现一个随机算法,以科学的手段来抽奖。高大上的名字,有种科学算命的感受。咱们排除一下程序员主观意愿的做弊行为,来思考一下他们写的随机算法到底公平不公平。通常电子抽奖的流程是,让领导喊开始,随便过一段时间后,领导再喊停。在这个过程当中,程序只有这两个输入控制命令。而且,为了效果,通常都会在大屏幕随机滚动一下各位参加抽奖同事们的头像或名字什么的。这里就有两个问题,滚动过程当中,到底选哪些头像上大屏幕滚动?滚动结束后,如何随机抽取n(n>1)个中奖者,从哪里抽?程序员
假设参与抽奖者有大概1000名。每次大屏幕只能显示顶多9名(九宫格,好看)。算法
按照参与者签到先来后到的顺序排序,每次从前面按顺序提取9名同事上墙。直到大佬喊停。这下好了。想露脸的同事们,赶忙早点去年会现场签到吧。若是去晚了,就石沉大海,杳无音讯了。这样写的程序员确定是在想,1000名一次从数据库中读取出来,怕性能有问题,或者将就以前写好的一个分页接口,正好在这里派上了用场。数据库
他会用点心思想一想什么叫公平。为了省下那一点点性能,在抽奖前一次读取全部1000名同事的头像信息,以空间换取时间嘛。而后调用随机数函数9次,按照9个随机数的结果从集合里抽取。抽取完后从集合中剔除,从新排序,总数做为下一次的随机范围,直到大佬喊停。若是轮完一圈了,大佬玩心大起,还未喊停。那就把剔除的同事再次放入集合中,相似扑克洗牌。这里的随机函数稍微懂程序的朋友们,也就是利用了一些系统自带的,好比javascript
的random
。这个好像稍微公平点吧?dom
当大佬终于喊停的时候,就开始启动抽奖随机算法,选择中奖者了。虽然你上墙了,可是没有被抽中,那有个屁用。因此关键仍是要看看程序员是如何实现抽奖算法的。即便没上墙,也没必要气馁,有机会,就看你碰上了什么样的程序员。函数
从前面上墙的参与者里选择n个中奖者,n必须小于上墙者总数。碰上这样的,仍是那句话,叫大家早点去年会现场,这下吃亏了吧?另外,有些领导就喜欢一开始就喊停,那大屏幕都还没滚动一屏,因此,你更应该早点去现场了。性能
首先他明白,待抽奖的集合千万不能只从上墙集合里抽取,那个仅仅是一个噱头,相似篮球比赛暂停期间的拉拉队表演而已。你见过有从啦啦队成员里选择一个MVP吗?因此,样本空间仍是1000个参与者。其实也很简单,利用系统随机数,从1000范围内抽取n个序号,按照序号找到中奖者就能够了。这样一来,甭管你是早来,仍是晚来,都不要紧了。google
前面说过,抽奖都是一轮一轮的抽的。因此,最起码,确定要保证每抽完一轮,就要将这些中奖者从参与者中剔除。不然一我的运气爆棚,祖坟冒青烟把全部奖都拿了,大家可别怪他做弊。code
这个我就很差多作论述了,我的能力有限,有兴趣的朋友们,能够去google一下,看看那个random方法,究竟是怎么返回一个随机数字的,它到底公平不公平。若是查到了的话,记得来这里评论留言分享哦。
最后,祝兄弟姐妹们年会中大奖,千万别碰到倒霉催的程序员和没领证的程序员。