如何设置随机种子使有序列表ADT测试每次以相同方式失败?
问题描述
我从没接触过random库,对代码里的FIXME注释完全摸不着头脑:有没有特定的种子值能让测试代码触发最后那个assert?
当前代码是用来测试有序列表ADT的,通过random库生成随机数,对有序列表执行添加或删除操作。代码片段如下:
import random from ordered_list import OrderedList def test_random_ops(): # FIXME: find a seed that gets this test to hit the last assert random.seed() ol = OrderedList() for _ in range(1000): num = random.randint(1, 10) if random.random() < 0.5: ol.add(num) else: ol.remove(num) # 最后一个断言 assert ol.size() == 0, "List should be empty after 1000 ops"
解答
- 先搞懂
random.seed()的作用:给随机数生成器设置一个固定种子后,每次运行代码都会生成完全一样的随机操作序列——这是核心,种子固定,增删的顺序就固定了。 - 你要找的种子,就是能让1000次随机增删后,有序列表刚好为空的那个值。
- 找种子的实用方法:
- 写个小循环遍历种子值(从0开始挨个试),每次设置种子后跑测试,检查是否通过最后一个断言:
import random from ordered_list import OrderedList def check_seed(seed): random.seed(seed) ol = OrderedList() for _ in range(1000): num = random.randint(1, 10) if random.random() < 0.5: ol.add(num) else: ol.remove(num) return ol.size() == 0 # 从0开始找,找到就打印 for seed in range(10000): if check_seed(seed): print(f"找到可用种子:{seed}") break - 原理很简单:不同种子对应不同的随机序列,总有一个序列能让增删次数刚好抵消,最后列表为空。
- 写个小循环遍历种子值(从0开始挨个试),每次设置种子后跑测试,检查是否通过最后一个断言:
- 为什么要固定种子?默认情况下
random用系统时间当种子,每次运行的随机序列都不一样,很难碰巧让最后列表为空;固定种子后,就能复现那个刚好满足条件的操作序列。
内容的提问来源于stack exchange,提问作者Moronis2234
相关产品推荐
相关产品推荐

