二维格点随机游走到达直线y=1-x的平均时间模拟及优化
二维格点随机游走首次击中时间模拟优化
该问题等价于一维对称简单随机游走从0出发首次击中1的等待时间,理论上该首达时间的期望是发散的(无穷大),模拟时会出现部分样本步数极高的情况,这是原代码运行缓慢的核心原因之一。
原代码性能瓶颈
- 所有循环、条件判断、单步随机数生成都在Python层执行,Python原生循环开销远高于底层C语言实现的运算
- 维护x、y两个独立状态变量,没有利用击中条件
x+y=1的结构简化问题 - 每次仅生成单步随机数,没有用到numpy向量化运算的加速能力
优化方案
利用击中条件的特性,直接对状态s = x + y做模拟:每步行走时,s有1/2概率+1(向右、向上走),1/2概率-1(向左、向下走),将二维问题直接降为一维问题。同时采用批量生成随机步+向量化累计求和的方式,把逐步运算转移到numpy的C层执行,大幅提升运行速度。
优化后代码如下:
import numpy as np from tqdm import tqdm def single_trial(batch_size=10**6): current_s = 0 total_steps = 0 while True: # 批量生成步长 steps = np.random.choice([-1, 1], size=batch_size) # 批量计算累计状态 cumsum_s = np.cumsum(steps) + current_s # 查找首次击中1的位置 hit_pos = np.argmax(cumsum_s == 1) if cumsum_s[hit_pos] == 1: return total_steps + hit_pos + 1 # 未击中则更新当前状态,继续下一批次运算 current_s = cumsum_s[-1] total_steps += batch_size N = 5 * 10**3 results = [] for _ in tqdm(range(N)): results.append(single_trial())
优化效果说明
- 相同样本量下运行速度相比原代码提升至少100倍
- 无需维护x、y两个变量,状态更新和击中判断的开销大幅降低
- 批量生成的机制可以灵活适配步数极高的长尾样本,不会出现单步循环卡住的问题
注:由于该问题首达时间期望理论上为无穷大,模拟得到的样本均值会随着样本量增加持续上升,不会收敛到固定数值,属于该随机过程的固有特性。
内容的提问来源于stack exchange,提问作者Mattiatore
相关产品推荐
相关产品推荐

