新的一年到了,相信很多公司都會舉辦年會吧!而年會中最歡迎的環節就是抽獎了,運氣好的能抽個大獎,開開心心回家過年;運氣不好的也沒事,重在參與嘛,就像我一樣,年年都沒咋中獎,但是仍然很期待抽獎,或許這就是人之本性吧,喜歡未知的驚喜,也叫隨機驚喜。
今天我就想來分析下抽獎的需求,對于傳統抽獎而言,一般都是HR把所有人的姓名跟一個號碼對應,然后用乒乓球也好,小紙條也好,反正有多少參與人就有多少抽獎物料。然后拿一個大箱子把所有的乒乓球或者號碼紙條放到箱子里面。開始抽獎時,就由某某領導開始用手隨機抽取。對于這種抽獎方式而言,抽完獎之后乒乓球或者紙條就沒用了,箱子也沒用了,難免有些不環保,所以我想著用代碼的方式實現抽獎。
熟悉了傳統的抽獎方式之后我們得知要抽獎首先有以下的必要條件:
- n個員工的號碼牌;
- 大箱子:抽獎池;
- 隨機抽取:滿足抽獎的公平性;
在滿足了上述必要條件之后我們用一句話歸納下抽獎算法:在n個員工中隨機選擇m名中獎者,已經中獎的人需要從抽獎池中去除(防止重復中獎),然后進行下一輪的隨機選擇,如此循環。除了在抽獎中應用之外,比如一些需要x位不重復的隨機數也可以用這個算法實現。
主要功能為:
- 構建n名員工工號;
- 定義一個抽獎池;
- 用random模塊下的choice()隨機選擇m名員工工號,為了說明問題,當前文章m等于1;
- 利用remove()移除已中獎的用戶,防止重復中獎;
下面直接上代碼:
1 | # _*_ coding:utf-8 _*_ |
運行上文代碼,我們得到下圖的結果:
可以看到,一共有9999名員工,我們假設一共3個獎項,一二三等獎各一名;第一次抽三等獎,獲獎者工號為7758,然后將中獎者移出抽獎池,現在的抽獎池只有9998名員工,然后依次循環,每抽中一名選手抽獎池就移出一名員工,這樣可以保證永遠不會重復中獎。
最后,一個簡單的抽獎小應用就寫完了,其實非常簡單。當然,我上面的代碼其實可以優化的地方非常多,也有一些不合理的地方,后續再優化吧。