Python 3.x 使用列表理解和随机性模拟抛硬币,代码首先工作,然后挂起

Python 3.x 使用列表理解和随机性模拟抛硬币,代码首先工作,然后挂起,python-3.x,simulation,Python 3.x,Simulation,掷硬币模拟有问题。这段代码应该计算一枚硬币连续三次抛出尾巴所需的平均翻转次数(因此一次成功=3't',1次成功满足第一个实验) 好的,我认为主要的问题是,success=''.join(experiment).count('ttt')行将导致您的程序在整个列表中搜索while循环中的每一次运行,这将是O(n^2)时间复杂度(也就是说,糟糕。运行的实验越多,真的很糟糕) 我突然启动了一个(基本的)程序,将在线性(O(n))时间内完成该部分: 随机导入 实验规模=[1,101001000100000

掷硬币模拟有问题。这段代码应该计算一枚硬币连续三次抛出尾巴所需的平均翻转次数(因此一次成功=3't',1次成功满足第一个实验)


好的,我认为主要的问题是,
success=''.join(experiment).count('ttt')
行将导致您的程序在整个列表中搜索while循环中的每一次运行,这将是O(n^2)时间复杂度(也就是说,糟糕。运行的实验越多,真的很糟糕)

我突然启动了一个(基本的)程序,将在线性(O(n))时间内完成该部分:

随机导入
实验规模=[1,1010010001000000]
对于实验大小中的数字:
last=False#跟踪最后3次翻转是否为尾部。False=不在乎,
#真=尾
last_2=错误
last_3=错误
成功=0
运行次数=0
成功<数量:
运行次数+=1
last_3=last_2#从最后一次翻转中跳到第三次
last_2=last
last=bool(random.getrandbits(1))#随机获取True或False
if(last&last_2&last_3):#如果全部为尾部
成功+=1
last,last_2,last_3=False,False,False#重置,因此必须得到3
#又是一排
打印(“运行:“+str(运行)+”\n成功:“+str(成功)+”\n平均值:“+str(运行/成功)+””\n”)

因为我们不是每次重复都遍历一个完整的列表,所以速度要快得多。

它在做什么?你有任何输出吗?@glibdud我实际上一直在运行它,只是想看看它是否一直有效,它确实有效,但我认为使用列表理解会让它花费比它应该花费的时间更长的时间。它几乎立即达到100个实验,然后速度以指数级的速度减慢。所以,我想看看在这个过程中是否有什么地方我可以优化或加速?从统计上看,平均翻转次数应该在14次左右。好吧,那么澄清一下:你正在试图了解使用101001000获得一串“ttt”(一行3个尾巴)所需的平均翻转次数。。。翻转?我的理解正确吗?10000次和100000次翻转所需的时间比1000次要长得多,这就是导致代码继续运行的原因,您认为它已挂起。@NickVitha正确!我想指出的是,我确信有比我写的更好的答案,所以有人可以自由地自己回答。
import random

experiments = [1, 10, 100, 1000, 10000, 100000]

for number in experiments:
    experiment = []
    success = 0
    while success < number:
        face = random.choice(['h','t'])
        experiment.append(face)
        success = ''.join(experiment).count('ttt')
    print(f'Experiments: {number}')
    print(f'Average flips: {len(experiment)/success}\n')
[evaluate troubleshooting.py]
Experiments: 1
Average flips: 27.0

Experiments: 10
Average flips: 6.4

Experiments: 100
Average flips: 14.39

Experiments: 1000
import random

experiment_size = [1,10,100,1000,10000,100000]

for number in experiment_size:
    last = False # track whether the last 3 flips were tails. False = don't care, 
                 # True = tails
    last_2 = False
    last_3 = False

    success = 0
    runs = 0
    while success < number:
        runs += 1
        last_3 = last_2 #bump the 3rd from last flip
        last_2 = last
        last = bool(random.getrandbits(1)) #get True or False, randomly
        if(last & last_2 & last_3): #if all are tails
            success += 1
            last, last_2, last_3 = False, False, False #reset so that you have to get 3
                                                       #in a row again
    print("Runs: " + str(runs) + "\nSuccesses: " + str(success) +"\nAverage: " + str(runs/success) + "\n")