微信紅包的概率測試程式
演算法: 比如100元發給10個人,每個紅包至少一元,那麼第1個最多得100-9=91,這樣才夠後面的人分. 第2個最多得剩下的減8,以此類推直到倒數第2人。最後1人直接得剩下的。 但是這樣一來,隨機性就變了。從實驗結果看,第一個就沒有得1的,後面很多個都得1。
#include <cstdio> #include <ctime> #include <cstdlib> void hb() { int total=100; int minv=1; int count=5; int sum=0; for(int c=1; c<=count; c++) { int x=rand()%(total-minv*(count-c))+minv; if(c==count )x=total; printf("%d ",x); total-=x; sum+=x; } printf(" =%d\n",sum); } int main() { srand(time(NULL)); for(int i=0; i<30; i++) hb(); }
測試結果
--------------------100發給5人 34 62 1 2 1 =100 38 19 18 4 21 =100 16 36 44 1 3 =100 93 4 1 1 1 =100 53 17 26 2 2 =100 22 56 9 1 12 =100 6 16 71 3 4 =100 43 44 4 3 6 =100 14 62 3 16 5 =100 30 29 2 7 32 =100 52 5 10 21 12 =100 75 10 6 8 1 =100 90 4 1 2 3 =100 74 14 4 2 6 =100 59 3 19 1 18 =100 91 4 2 2 1 =100 64 27 2 4 3 =100 25 64 3 1 7 =100 2 83 3 6 6 =100 88 3 7 1 1 =100 14 66 7 2 11 =100 3 15 12 47 23 =100 43 49 5 2 1 =100 61 2 7 4 26 =100 16 79 3 1 1 =100 61 13 7 2 17 =100 41 52 4 1 2 =100 78 16 2 2 2 =100 34 34 26 1 5 =100 26 50 19 3 2 =100 -----------------------------100發給10人 57 2 12 15 1 9 1 1 1 1 =100 10 51 21 2 9 3 1 1 1 1 =100 27 2 3 42 11 1 2 1 7 4 =100 74 5 10 4 2 1 1 1 1 1 =100 57 26 1 6 3 2 2 1 1 1 =100 71 2 3 12 7 1 1 1 1 1 =100 82 2 4 3 1 1 4 1 1 1 =100 51 17 9 1 11 7 1 1 1 1 =100 85 3 2 3 1 1 2 1 1 1 =100 42 35 6 8 2 3 1 1 1 1 =100 39 14 20 14 6 3 1 1 1 1 =100 78 3 11 2 1 1 1 1 1 1 =100 24 43 21 4 2 1 2 1 1 1 =100 79 13 1 1 1 1 1 1 1 1 =100 1 70 7 11 1 3 1 3 2 1 =100 87 5 1 1 1 1 1 1 1 1 =100 70 20 3 1 1 1 1 1 1 1 =100 8 34 45 3 1 4 2 1 1 1 =100 35 51 2 6 1 1 1 1 1 1 =100 26 57 2 3 3 3 3 1 1 1 =100 78 10 1 1 4 2 1 1 1 1 =100 81 5 3 3 2 2 1 1 1 1 =100 81 5 6 1 2 1 1 1 1 1 =100 26 60 4 1 3 1 1 1 1 2 =100 78 10 1 4 1 1 2 1 1 1 =100 88 1 3 2 1 1 1 1 1 1 =100 84 7 2 1 1 1 1 1 1 1 =100 50 10 20 5 5 6 1 1 1 1 =100 77 10 1 6 1 1 1 1 1 1 =100 42 29 3 18 3 1 1 1 1 1 =100 ------------------------------1000發給10人 299 665 4 1 21 4 3 1 1 1 =1000 887 88 18 1 1 1 1 1 1 1 =1000 719 161 112 2 1 1 1 1 1 1 =1000 276 268 216 46 156 23 9 3 1 2 =1000 620 160 169 42 4 1 1 1 1 1 =1000 700 230 52 3 9 1 1 2 1 1 =1000 541 313 120 4 16 1 1 2 1 1 =1000 695 183 18 62 23 3 2 4 4 6 =1000 307 417 21 81 155 13 3 1 1 1 =1000 894 14 63 8 2 4 7 6 1 1 =1000 428 543 5 15 2 3 1 1 1 1 =1000 83 61 391 52 165 202 34 6 1 5 =1000 492 205 75 180 17 8 4 7 5 7 =1000 971 8 10 5 1 1 1 1 1 1 =1000 381 140 167 246 30 18 7 8 2 1 =1000 403 553 3 18 15 4 1 1 1 1 =1000 456 98 105 188 103 32 2 8 4 4 =1000 990 2 1 1 1 1 1 1 1 1 =1000 77 70 86 521 133 42 20 49 1 1 =1000 585 158 122 35 90 1 6 1 1 1 =1000 645 327 20 2 1 1 1 1 1 1 =1000 711 198 52 24 4 3 3 3 1 1 =1000 432 517 36 6 3 2 1 1 1 1 =1000 181 94 185 152 346 15 17 3 2 5 =1000 277 60 483 56 43 41 18 14 2 6 =1000 669 216 64 33 4 5 1 1 2 5 =1000 346 378 125 111 6 13 3 14 3 1 =1000 171 523 88 86 89 27 6 2 2 6 =1000 554 63 344 20 2 13 1 1 1 1 =1000 405 526 10 38 13 2 1 2 1 2 =1000
我又想到1種思路,最初就確定最終發包的數量,生成與人數相同的隨機數,然後將隨機數排序,按順序發給不同金額,但第幾名得多少不好確定。
https://www.zhihu.com/question/22625187
提到,每個包的上限是剩餘均值的2倍,根據這個思路,把分配的語句改為int x=rand()%(total*2/(count-c+1))+minv;
,這樣方差小多了。
------------------------------100發給10人 10 2 4 10 23 9 5 4 31 2 =100 6 16 3 9 19 8 17 7 12 3 =100 19 4 18 16 7 5 1 17 5 8 =100 4 6 10 20 12 4 19 13 2 10 =100 15 14 11 12 15 12 7 8 3 3 =100 20 13 12 3 13 3 18 9 4 5 =100 6 4 20 1 1 25 21 2 19 1 =100 6 19 6 17 13 4 2 10 16 7 =100 15 11 16 1 3 3 13 25 8 5 =100 1 19 15 17 11 3 11 7 7 9 =100 1 5 8 16 11 5 16 10 22 6 =100 10 15 10 9 12 15 7 8 4 10 =100 5 18 2 11 16 8 18 8 9 5 =100 5 4 3 5 19 19 10 15 9 11 =100 2 2 3 11 27 21 8 16 6 4 =100 18 2 5 4 7 10 27 3 7 17 =100 18 18 8 10 11 13 6 1 4 11 =100 10 17 5 7 11 12 6 6 17 9 =100 13 7 15 14 9 12 11 7 4 8 =100 4 13 18 11 18 7 10 12 4 3 =100 12 5 17 14 1 6 20 10 5 10 =100 14 12 3 1 16 10 4 12 15 13 =100 5 5 1 11 18 15 11 17 4 13 =100 18 5 17 4 12 14 1 11 7 11 =100 8 1 12 8 8 6 11 8 27 11 =100 10 2 4 19 6 19 2 14 4 20 =100 17 8 4 4 7 21 16 2 11 10 =100 11 15 11 8 12 9 10 1 2 21 =100 8 6 2 5 7 7 8 22 10 25 =100 17 13 9 5 18 11 4 11 8 4 =100 ------------------------------------------1000發給10人 200 12 70 148 166 44 157 20 80 103 =1000 70 94 5 196 185 58 78 134 99 81 =1000 187 70 95 30 104 76 27 242 151 18 =1000 110 5 44 164 152 58 222 152 13 80 =1000 190 55 182 26 169 151 52 70 27 78 =1000 74 87 66 17 108 78 26 25 55 464 =1000 5 75 16 144 240 202 129 8 137 44 =1000 32 24 208 71 121 213 57 51 132 91 =1000 144 26 106 94 196 159 84 48 85 58 =1000 73 151 8 196 32 125 131 29 191 64 =1000 139 79 99 94 81 76 113 156 105 58 =1000 88 131 148 136 6 68 191 5 114 113 =1000 142 174 44 84 184 85 138 80 52 17 =1000 18 173 96 51 48 50 250 103 123 88 =1000 79 62 66 160 108 157 130 40 80 118 =1000 30 214 111 38 108 35 190 176 10 88 =1000 14 187 38 203 59 163 24 171 72 69 =1000 78 62 94 33 201 169 161 65 73 64 =1000 121 17 80 87 165 92 158 29 7 244 =1000 198 92 111 40 137 3 132 83 171 33 =1000 193 92 160 43 105 155 33 37 77 105 =1000 12 74 173 130 101 59 94 166 8 183 =1000 164 108 71 72 36 88 230 10 101 120 =1000 33 68 170 91 61 59 20 107 360 31 =1000 140 166 23 186 2 41 159 101 16 166 =1000 6 101 187 137 10 78 30 124 204 123 =1000 191 42 106 91 120 130 90 38 96 96 =1000 66 5 8 234 208 33 193 160 78 15 =1000 192 86 74 17 183 1 12 216 115 104 =1000 35 160 44 84 79 33 231 125 101 108 =1000
看最佳手氣出現的位置。
#include <cstdio> #include <ctime> #include <cstdlib> static int best_count[11]={0}; void hb() { int total=1000; int minv=1; int count=10; int sum=0; int best=0,bestpos=0; for(int c=1; c<=count; c++) { int x=rand()%(total*2/(count-c+1))+minv; if(c==count )x=total; if(x>best) { best=x; bestpos=c; } //printf("%d ",x); total-=x; sum+=x; } //printf(" sum=%d bestpos=%d\n",sum,bestpos); best_count[bestpos]++; } int main() { srand(time(NULL)); for(int i=0; i<10000; i++) hb(); for(int c=0; c<=10; c++) printf("best_count[%d]=%d\n",c,best_count[c]); }
結果,2~7輪抽中的概率明顯低
best_count[0]=0 best_count[1]=1074 best_count[2]=946 best_count[3]=929 best_count[4]=835 best_count[5]=910 best_count[6]=915 best_count[7]=971 best_count[8]=1077 best_count[9]=1169 best_count[10]=1174 D:\>a best_count[0]=0 best_count[1]=1003 best_count[2]=958 best_count[3]=918 best_count[4]=915 best_count[5]=887 best_count[6]=907 best_count[7]=998 best_count[8]=1053 best_count[9]=1197 best_count[10]=1164 D:\>a best_count[0]=0 best_count[1]=1095 best_count[2]=963 best_count[3]=945 best_count[4]=855 best_count[5]=892 best_count[6]=909 best_count[7]=965 best_count[8]=1035 best_count[9]=1148 best_count[10]=1193
這個演算法還有一個明顯的問題,第一輪最多抽總數*0.2的金額,後面的可能抽到更大的。
---測試100次 best_value[0]=0 best_value[1]=199 best_value[2]=195 best_value[3]=206 best_value[4]=224 best_value[5]=248 best_value[6]=235 best_value[7]=242 best_value[8]=306 best_value[9]=400 best_value[10]=262 ---測試100次 best_value[0]=0 best_value[1]=200 best_value[2]=218 best_value[3]=218 best_value[4]=235 best_value[5]=238 best_value[6]=258 best_value[7]=304 best_value[8]=259 best_value[9]=307 best_value[10]=415
相關文章
- 騰訊筆試題--微信紅包筆試
- 基於Auto.js的微信紅包監測JS
- 如何測試微信小程式微信小程式
- 微信小程式搶紅包實現效果微信小程式
- Appium 之測試微信小程式APP微信小程式
- Appium之測試微信小程式APP微信小程式
- 微信小程式搶紅包高併發設計微信小程式
- 微信紅包介面呼叫(rails)AI
- iOS 如何測試微信小遊戲&小程式?iOS遊戲
- iOS如何測試微信小遊戲&小程式?iOS遊戲
- 微信小程式之滲透測試、加固、安全檢測微信小程式
- 微信商戶 API 發紅包!API
- Android如何測試微信小遊戲&小程式?Android遊戲
- 手把手教你測試微信小程式,附軟體測試員必知的20個常見測試點微信小程式
- 微信小程式設計師自動化測試微信小程式程式設計師
- 微信紅包體系設計分析
- 高仿微信搶紅包動畫特效動畫特效
- 微信分享測試步驟
- 微信 Linux 測試版Linux
- CI Weekly #12 | 微信小程式的自動化測試進階微信小程式
- 【案例】用Jmeter做微信小程式專案介面測試JMeter微信小程式
- 用Jmeter做微信小程式專案介面測試【案例】JMeter微信小程式
- 微信小程式-測試遊戲生成六邊多邊形微信小程式遊戲
- 在微信小程式中打造 MQTT 連線測試工具微信小程式MQQT
- 微信轟炸程式,博主親測,歪心思勿試
- 微信小程式真機預覽體驗測試教程微信小程式
- 如何做微信紅包封面專案?
- 微信公眾號下發紅包 -- PHPPHP
- 網站安全滲透測試該如何增加就業概率網站就業
- 微信小程式測試過程中的各個要點(乾貨)微信小程式
- Python教你全自動搶微信紅包Python
- 微信搶紅包遊戲繞過指定尾數遊戲
- 微信紅包火了,釣魚網站樂了網站
- 微信小程式 TypeScript 嘗試微信小程式TypeScript
- 測試程式
- 如何選擇測試微信域名檢測介面-域名檢測api介面測試標準API
- falseShare的測試程式False
- 模擬微信搶紅包demo,生成隨機數隨機