Python 使用随机变量的模拟输出差异

Python 使用随机变量的模拟输出差异,python,random,simulation,Python,Random,Simulation,我试图通过生成模拟来找到股价从25美元下跌到18美元的预期时间步数。从分析上可以看出,所需的预期时间步数为129 以下3个代码在我看来基本相同,但给出了不同的结果 第一个返回平均100个时间步: target = 18 support_level = 20 I = [] n = 50000 for i in range(n): stock_price = 25 t = 0 while stock_price != target: t += 1

我试图通过生成模拟来找到股价从25美元下跌到18美元的预期时间步数。从分析上可以看出,所需的预期时间步数为129

以下3个代码在我看来基本相同,但给出了不同的结果

第一个返回平均100个时间步:

target = 18
support_level = 20
I = []
n = 50000

for i in range(n):
    stock_price = 25
    t = 0
    
    while stock_price != target:

        t += 1

        if stock_price < support_level:
            stock_price += random.choices([-1, 1], weights=[1/3, 2/3])[0]

        if stock_price == support_level:
            stock_price += random.choices([-1, 1], weights=[0.1, 0.9])[0]

        if stock_price > support_level:
            stock_price += random.choices([-1, 1], weights=[2/3, 1/3])[0]
    
    I.append(t)
sum(I) / len(I)

区别是什么?

前两种区别是
if
/
if
/
if
,第三种区别是
if
/
elif
/。后者在我看来是正确的。前者可能在同一循环迭代中执行多个块,因此它们会更快地收敛。在运行每个算法之前,您应该设置相同的种子(例如
random.seed(123)
)。这提供了更好的比较。正如@Thomas所提到的,
uniform
choices
提供了不同的分布,因此不能期望相同的结果。@Thomas这就是OP重复它50k次的原因。假设结果为泊松分布,计算平均值应为分析结果的+/-0.05(即
sqrt(129/50000)
)expectation@Thomas你说得对,谢谢!
for i in range(n):
    stock_price = 25
    t = 0
    
    while stock_price != target:
        x = random.uniform(0, 1)
        t += 1

        if stock_price < support_level:
            if x <= 2/3:
               stock_price += 1
            else:
               stock_price -= 1

        if stock_price == support_level:
            if x <= 0.9:
               stock_price += 1
            else:
               stock_price -= 1

        if stock_price > support_level:
            if x <= 1/3:
               stock_price += 1
            else:
               stock_price -= 1
    
    I.append(t)
for i in range(n):
    p=25
    t=0

    while p != 18:
        if(p==20):
            dist = [0.1, 0.9]
        elif(p>20):
            dist = [2/3, 1/3]
        else:
            dist = [1/3, 2/3]

        p=p+random.choices(direction, dist)[0]
        t+=1
        
    I.append(t)
    
sum(I)/len(I)