如何为不同红色射手准确率运行代码?异常结果排查求助
问题排查:概率模拟代码中的异常结果
正常运行的代码及输出
当单独调用函数时,代码运行正常:
from IPython.core import history from numpy.random import default_rng import numpy as np rng = default_rng(42) def trial(red,blue , red_accurcy = 1, blue_accurcy = 1, history = False ,debug = False): if history: red_history = [red] blue_history = [blue] if debug: print(f"Start:\t red = {red:3d} blue = {blue:3d}") while red and blue: p = np.array([red,blue] , dtype = float) p /= p.sum() arrow = rng.choice(['red' , 'blue'] , p=p) if arrow == 'red': blue -= 1 if rng.uniform() < red_accurcy else 0 else: red -= 1 if rng.uniform() < blue_accurcy else 0 if debug: print(f"\t red = {red:3d} blue = {blue:3d} arrow = {arrow}") if history: red_history.append(red) blue_history.append(blue) if debug: print(f"End:\t red = {red:3d} blue = {blue:3d}") if history: return red,blue, red_history, blue_history else: return red, blue ,red_accurcy ,blue_accurcy trial(90,45,0.1,0.2)
输出:
(60, 0, 0.1, 0.2)
异常场景的代码及输出
尝试遍历红色射手不同准确率时,结果异常:
red_ac = np.linspace(0,1,10) battles = [trial(90,45,red_accurcy=red_ac,blue_accurcy= 1) for red_ac in range(10)] battles
输出:
[(0, 45, 0, 1), (75, 0, 1, 1), (82, 0, 2, 1), (80, 0, 3, 1), (78, 0, 4, 1), (74, 0, 5, 1), (69, 0, 6, 1), (74, 0, 7, 1), (81, 0, 8, 1), (81, 0, 9, 1)]
错误原因分析
- 循环变量误用:你生成了
red_ac = np.linspace(0,1,10)来获取0到1之间的10个浮点准确率,但列表推导式中却用for red_ac in range(10)遍历0-9的整数,完全没用到之前生成的浮点数组。 - 准确率参数越界:循环中传入
red_accurcy的是0-9的整数,而准确率的合理范围是0到1。当red_accurcy > 1时,rng.uniform() < red_accurcy永远为True,红色射手每次射箭必中,导致蓝色射手几乎不可能获胜(仅当red_accurcy=0时红色全不中,蓝色才能赢)。
修正后的代码
red_ac = np.linspace(0,1,10) # 改用遍历生成的浮点数组,避免变量名冲突 battles = [trial(90,45,red_accurcy=rac,blue_accurcy=1) for rac in red_ac] battles
修正后,传入的red_accurcy会是0、0.111...、0.222...直到1的合理数值,模拟结果会符合预期。
内容的提问来源于stack exchange,提问作者Ahmad Morwat
相关产品推荐
相关产品推荐

