pythonのrandom

高体連派遣の合間に1から50までの整数から20個の整数をランダムに選択するスクリプトを作成。なぜにエントリのカテゴリがrefereeになっているかというと、それは11月14日、15日に行われる某会で用意するなにかに関係があるからです。

最初に作成したスクリプトはこんなの。

#!/usr/bin/python

import random
b=[]
while 1:
    a=int(50*random.random())+1
    if a not in b:
        b.append(a)
    if(len(b) == 20):
        break
b.sort()
print  b

実際に動かしてみるとこんな結果。

$ ./mmm.py 
[4, 5, 9, 11, 15, 16, 19, 20, 21, 22, 25, 27, 28, 30, 32, 37, 38, 39, 41, 42]
$ ./mmm.py 
[4, 7, 9, 12, 13, 14, 16, 20, 21, 23, 24, 25, 26, 30, 31, 38, 43, 44, 45, 47]
$ ./mmm.py 
[1, 2, 5, 6, 8, 10, 11, 15, 17, 20, 25, 26, 27, 30, 32, 33, 37, 38, 46, 47]

ん〜、いいのかな。なんだか偏りがあるような気がしませんか?
ということでさっそく検証してみる。上記のスクリプトを100万回ループさせて、各数字毎に選択された回数を数える。100万回×2/5=40万回くらいが平均になればいいはず。

検証用スクリプトはこんなの。

#!/usr/bin/python

import random
c={}
while i < 1000000:
    b=[]
    while 1:
        a=int(50*random.random())+1
        if a not in b:
            b.append(a)
            if c.has_key(a):
                c[a]=c[a]+1
            else:
                c[a]=1
        if(len(b) == 20):
            break
    i=i+1

tmp_list=c.items()
tmp_list.sort(key=lambda x:x[1])

i=0
while i < 50:
    print "%02d:%d" % (tmp_list[i][0],tmp_list[i][1])
    i=i+1

技術的には別に難しくありません。ramdomで1から50までの整数を作成する度に、ディクショナリのカウントアップをして、valueでsortして出力。で結果はこんな。

$ ./mm.py 
47:399191
35:399197
43:399227
40:399305
09:399350
03:399366
33:399507
18:399530
14:399546
28:399570
26:399582
29:399621
34:399649
21:399661
24:399718
36:399738
12:399763
32:399779
23:399785
08:399833
44:399859
11:399868
15:399871
25:399882
06:399912
42:399921
27:399926
19:399951
20:400004
48:400035
05:400087
46:400161
31:400224
41:400239
17:400270
02:400274
30:400333
04:400342
10:400391
16:400416
39:400460
13:400540
01:400640
37:400696
49:400720
22:400737
50:400737
07:400745
45:400839
38:401002

もっとも多く選ばれた"38"ともっとも少なく選ばれた"47"の差は1.0045倍。

もう一回。

$ ./mm.py 
50:398981
20:399069
30:399228
21:399286
37:399329
22:399339
25:399367
11:399407
10:399420
38:399519
26:399550
36:399584
29:399624
40:399670
04:399704
45:399706
09:399714
03:399724
08:399746
31:399768
42:399848
43:399915
44:399920
14:399966
48:399999
27:400056
02:400061
24:400062
33:400069
41:400208
18:400237
28:400238
15:400300
06:400311
32:400312
12:400376
46:400408
47:400422
01:400429
34:400439
19:400445
49:400448
05:400454
13:400556
39:400622
17:400644
35:400668
07:400704
23:400871
16:401277

こんどは1.0057倍。

ふむ、少なくとも日本の衆議院選挙における一票の格差よりは差分が少ないようなので、偏りはないようです。ということで、これで20問選択して作成します。