不等概率随机数算法
每一门编程语言必不可少的一个模块(库)就是random库。以Python为例,Python的random属于标准库模块,其中的函数都是等概率生成一个随机数。如果想要生成不等概率的随机数,例如生成1和2两个数,出现1的概率为60%,出现2的概率为40%,要如何解决这个问题呢?
不难想到,random中的random函数会生成一个在区间[0,1)之间的随机小数,我们只需要将[0,1)在数轴上分成长度为6:4的两部分,当生成的小数落在长度占6/10的区间内,则生成1;若生成的小数落在长度占4/10的区间内,则生成2。
有了这个基本模型后,可以将此过程转换成代码:
1def my_ramdom():
2 num = random.random()
3 if num
4 result = 1
5 else:
6 result = 2
7
8 return result
测试
接下来将在问卷星中测试一下该算法的具体实现。在问卷星中设置问卷,其中两个单选,两个多选。
同样的,利用爬虫进行问卷星的问卷提交。首先自己手动填写一份问卷并提交,按F12查看post请求的地址与参数,我们可以得到以下的结果(由于问卷星在提交后有一个重定向的过程,要在火狐的开发者工具中勾选持续记录选项或谷歌中的preserve log选项)
可以发现,问卷星的结果是通过一个表单进行提交的。表单中的数据规律也不难理解:“1$”表示第一题,“1}”表示选择A选项;多项选择则通过“|”对选项进行分隔。因此我们在提交的时候构造相同的数据结构即可。
实现代码如下(相应的概率在代码的注释中):
1def choice():
2 result = ""
3 for i in range(4):
4 # 设置第一题概率为A=10%, B=20%,C=30%,D=40%
5 if i == 0:
6 temp = random.random()
7 result += "1$"
8 if temp
9 result += "1}"
10 elif temp >= 0.1 and temp
11 result += "2}"
12 elif temp >= 0.3 and temp
13 result += "3}"
14 else:
15 result += "4}"
16 # 设置第二题概率为A=80%,B=5%,C=5%,D=10%
17 elif i == 1:
18 temp = random.random()
19 result += "2$"
20 if temp
21 result += "1}"
22 elif temp >= 0.8 and temp
23 result += "2}"
24 elif temp >= 0.85 and temp
25 result += "3}"
26 else:
27 result += "4}"
28 # 设置第三题概率ABCD=10%,AC=50%,BCD=30%,AD=10%
29 elif i == 2:
30 temp = random.random()
31 result += "3$"
32 if temp
33 result += "1|2|3|4}"
34 elif temp >= 0.1 and temp
35 result += "1|3}"
36 elif temp >= 0.6 and temp
37 result += "2|3|4}"
38 else:
39 result += "1|4}"
40 # 设置第四题概率A,B,C,D相等
41 elif i == 3:
42 result += "4$"
43 temp = random.randint(1,4)
44 result += str(temp)
45
46 return result
由于问卷星在短时间内快速提交会出现验证码,因此在主程序的循环中要设置每10s提交一份,每提交3~4份停止30s,即每分钟3~4份;算下来一小时能提交200份左右,速度还算可以接受。
(耗时半个多小时提交120份)
得到的结果显然符合设定的概率: