题目
法一
基于蒙特卡罗法,随机数求取期望。
import random
def M():
Num = []
s = 10000
for i in range(s):
A, B = True, True
n = 0
while A or B:
p = random.random()
if p <= 0.20:
pp = random.random()
if pp <= 0.25:
A = False
else:
B = False
n += 1
Num.append(n)
return sum(Num)/s * 100 #算模拟s次的平均抽取次数,再乘单价
Num = []
for i in range(1000):
n = M()
Num.append(n)
print(sum(Num)/len(Num)) #再求一次平均
结果:2166.742980000003
法二
A:抽取次数的序列中,该次数下抽到A;
B:同上,抽到B;
C:同上,都没抽中。
n:抽取次数
a:以A结尾的事件;
b:以B结尾的事件。
P
(
n
)
=
P
(
a
)
+
P
(
b
)
=
∑
i
=
1
n
−
1
C
n
−
1
i
P
(
B
)
i
P
(
C
)
n
−
1
−
i
P
(
A
)
+
∑
i
=
1
n
−
1
C
n
−
1
i
P
(
A
)
i
P
(
C
)
n
−
1
−
i
P
(
B
)
P
=
∑
n
=
2
+
∞
P
(
n
)
—————————————————————
P
(
A
)
=
0.05
P
(
B
)
=
0.15
P
(
C
)
=
1
−
P
(
A
)
−
P
(
B
)
=
0.8
\large P(n) = P(a) + P(b) = \sum_{\mathclap{i = 1}}^{n-1} C_{n-1}^{i} P(B)^{i} P(C)^{n-1-i} P(A) \\+\sum_{\mathclap{i = 1}}^{n-1} C_{n-1}^{i} P(A)^{i} P(C)^{n-1-i} P(B)\\ P = \sum_{\mathclap{n = 2}}^{+\infty} P(n)\\ \normalsize \text{---------------------------------------------------------------}\\ \small P(A) = 0.05\\ P(B) = 0.15\\ P(C) = 1-P(A)-P(B) = 0.8
P(n)=P(a)+P(b)=i=1∑n−1Cn−1iP(B)iP(C)n−1−iP(A)+i=1∑n−1Cn−1iP(A)iP(C)n−1−iP(B)P=n=2∑+∞P(n)—————————————————————P(A)=0.05P(B)=0.15P(C)=1−P(A)−P(B)=0.8
def C(m,n): #C排列组合,m>n;m在下、n在上
fenzi,fenmu = 1,1
for i in range(n):
fenzi *= (m-i)
fenmu *= (i+1)
return fenzi/fenmu
def p(n):
numa, numb = 0, 0 #以A、以B结尾的概率
for i in range(n-1):
numa += C((n-1),(i+1))*pow(0.15,(i+1))*pow(0.8,(n-i-2))*0.05
numb += C((n-1),(i+1))*pow(0.05,(i+1))*pow(0.8,(n-i-2))*0.15
return numa + numb
def main():
num = 0
for i in range(2,1000):
num += i*p(i) #次数期望
print(num*100)
main()
结果:2166.6666666666693
法三
基于穷举可能的排列组合。
A:抽取次数的序列中,该次数下抽到A;
B:同上,抽到B;
C:同上,都没抽中。
以集合形式,达到去重。
但是电脑带不起来
def sub(string, p, c): #替换字符串中的某个位置上的字符
new = []
for s in string:
new.append(s)
new[p] = c
return ''.join(new)
def ss(n): #列举恰好抽n次时所有可能的排列组合
ls = ''
del_ss = [] #删除“CCC...CCA”和“CCC...CCB”的情况
num = 0
for i in range(n):
ls += 'C'
lt = sub(ls, -1, 'B')
del_ss.append(lt)
sb = set() #建立以B为最后一位的集合sb
for i in range(n-1):
for t in ['A', 'C']:
temp = sub(lt, i, t)
sb.add(temp) #将除最后一位,其他位置分别替换成A或C
for i in range(n-1):
s = sb #在原有基础上 不断将更多的A填入位置
for k in range(len(s)):
tt = s.pop()
for j in range(n-1):
for t in ['A', 'C']:
temp = sub(tt, j, t)
sb.add(temp)
lt = sub(ls, -1, 'A')
del_ss.append(lt)
sa = set() #建立以A为结尾的集合
for i in range(n-1):
for t in ['B', 'C']:
temp = sub(lt, i, t)
sa.add(temp)
for i in range(n-1):
s = sa
for k in range(len(s)):
tt = s.pop()
for j in range(n-1):
for t in ['B', 'C']:
temp = sub(tt, j, t)
sa.add(temp)
ss = sa|sb #合并
for t in del_ss:
ss.discard(t)
return ss #恰好为n次情况集合
def p(n):
s = ss(n)
num = 0 #恰好为n次的概率
try:
for i in range(len(s)):
t = s.pop()
a = t.count('A')
b = t.count('B')
c = t.count('C')
num += pow(0.05,a)*pow(0.15,b)*pow(0.80,c)
except:
pass
return num*n #单独次数期望
num = 0 #总次数期望
for i in range(2,100):
num += p(i)
print(i, p(i))
print(num*100)
以下为恰好n次的概率:
2 0.015
3 0.025500000000000002
4 0.0325875
5 0.03710625000000001
6 0.03970884374999999
7 0.040898221874999995
8 0.04106038804687501
9 0.04049016832031249
10 0.03941146682871092
11 0.037993171133027234
12 0.036361621983264335
13 0.034610372606357735
14 0.032807811921075715
15 0.031003106363202255
16 0.029230819955397797
17 0.02751449683378824
18 0.0258694306286361