独立随机变量和与分布卷积不符?numpy实验问题排查
问题1:为什么numpy.convolve结果和变量和的分布不匹配?
你混淆了采样数据的卷积和概率分布的卷积。numpy.convolve是对输入的数值序列做数学上的卷积运算,而随机变量和的分布对应的是它们**概率密度函数(PDF)**的卷积,不是直接对采样出来的随机数数组做卷积。
错误原因
你直接用np.random.uniform生成的采样数组做卷积,本质是把两个长度1e5的序列做卷积,得到的是长度199999的序列,这些数值是两个数组中元素的乘积和,完全不是概率分布的卷积。
正确做法:对概率密度函数做卷积
要得到两个均匀分布和的三角分布,需要先构造它们的离散PDF,再做卷积:
import numpy as np import matplotlib.pyplot as plt # 构造[0,1]均匀分布的离散PDF n_bins = 1000 x = np.linspace(0, 1, n_bins) pdf_uniform = np.ones(n_bins) # 均匀分布PDF为1 # 计算两个PDF的卷积,再归一化(因为卷积后总面积是1*1=1,但离散化需要调整) convolution_pdf = np.convolve(pdf_uniform, pdf_uniform, mode='full') # 卷积后的x轴范围是0到2,对应长度2n_bins-1 x_convolve = np.linspace(0, 2, 2*n_bins - 1) # 归一化,保证总面积为1 convolution_pdf = convolution_pdf / np.trapz(convolution_pdf, x_convolve) # 对比采样和的分布与PDF卷积结果 plt.figure(figsize=(10,5)) plt.subplot(1,2,1) uniform_sum = np.random.uniform(0,1,100000) + np.random.uniform(0,1,100000) plt.hist(uniform_sum, bins=50, density=True, alpha=0.7, label='Sample Sum') plt.title('Sum of Uniform Distributions') plt.legend() plt.subplot(1,2,2) plt.plot(x_convolve, convolution_pdf, label='PDF Convolution') plt.title('Convolution of Uniform PDFs') plt.legend() plt.show()
运行后你会看到右边的曲线和左边的直方图完全匹配,是标准的三角分布。
问题2:状态转移矩阵中求解总成本分布(动态规划+卷积)
针对带成本分布的状态转移问题,核心思路是动态规划+分布卷积,逐步计算每个状态的总成本分布。
核心逻辑
- 状态定义:用
dp[s]表示到达状态s时的总成本分布,存储为离散的PDF数组(包含x轴取值和对应的概率密度)。 - 初始状态:起始态
start的总成本分布是点分布——成本为0,概率密度无穷大(离散化后是一个峰值,总面积为1)。 - 状态转移:对于每个状态
s,遍历所有从s到s'的转移:- 转移概率为
p - 转移成本的分布为
cost_dist(离散PDF) - 则到达
s'的新增成本分布是dp[s]和cost_dist的卷积(对应两步成本的和) - 将这个新增分布乘以
p,加到dp[s']的现有分布上
- 转移概率为
- 终止条件:当处理到终态,或者所有可能的转移都迭代完成后,
dp[end]就是所求的总成本分布。
实现细节
- 离散分布表示:用两个数组存储,比如
(x_vals, pdf_vals),x_vals是成本的离散取值,pdf_vals是对应的概率密度。 - 卷积优化:对于大规模计算,用
numpy.fft实现快速卷积(FFT卷积),比直接用np.convolve快得多。 - 分布合并:当多个转移路径贡献同一状态的成本分布时,需要将它们的PDF按x轴对齐后相加(加权转移概率)。
简单示例代码
假设我们有3个状态:start→mid→end,转移规则:
start到mid:概率0.6,成本服从[0,1]均匀分布;概率0.4,成本服从[1,2]均匀分布mid到end:概率1.0,成本服从正态分布N(1, 0.1)
import numpy as np import matplotlib.pyplot as plt def create_discrete_dist(x_start, x_end, n_bins, dist_type='uniform', **kwargs): """创建离散概率分布""" x = np.linspace(x_start, x_end, n_bins) if dist_type == 'uniform': pdf = np.ones(n_bins) elif dist_type == 'normal': mu = kwargs.get('mu') sigma = kwargs.get('sigma') pdf = np.exp(-(x - mu)**2 / (2 * sigma**2)) / (sigma * np.sqrt(2 * np.pi)) # 归一化 pdf = pdf / np.trapz(pdf, x) return x, pdf def convolve_dist(dist1, dist2): """卷积两个离散分布,返回新的(x, pdf)""" x1, pdf1 = dist1 x2, pdf2 = dist2 # 计算卷积后的x轴范围 x_min = x1[0] + x2[0] x_max = x1[-1] + x2[-1] # 用FFT做快速卷积 n = len(pdf1) + len(pdf2) - 1 fft1 = np.fft.fft(pdf1, n) fft2 = np.fft.fft(pdf2, n) conv_pdf = np.fft.ifft(fft1 * fft2).real # 生成新的x轴 x_conv = np.linspace(x_min, x_max, n) # 归一化 conv_pdf = conv_pdf / np.trapz(conv_pdf, x_conv) return x_conv, conv_pdf # 初始化状态分布 n_bins = 500 dp = {} # 起始态:成本0,概率1(离散化为窄峰) start_x = np.array([0.0]) start_pdf = np.array([1e10]) # 近似点分布 dp['start'] = (start_x, start_pdf) # 定义转移规则 transitions = { 'start': [ {'to': 'mid', 'prob': 0.6, 'cost_dist': create_discrete_dist(0, 1, n_bins)}, {'to': 'mid', 'prob': 0.4, 'cost_dist': create_discrete_dist(1, 2, n_bins)} ], 'mid': [ {'to': 'end', 'prob': 1.0, 'cost_dist': create_discrete_dist(0.7, 1.3, n_bins, dist_type='normal', mu=1, sigma=0.1)} ] } # 执行动态规划迭代 for _ in range(2): # 这里只有两步转移,迭代2次足够 new_dp = dp.copy() for s in transitions: if s not in dp: continue for trans in transitions[s]: to_s = trans['to'] prob = trans['prob'] cost_dist = trans['cost_dist'] # 卷积当前状态分布和转移成本分布 conv_x, conv_pdf = convolve_dist(dp[s], cost_dist) # 加权转移概率 conv_pdf *= prob # 合并到目标状态的分布 if to_s not in new_dp: new_dp[to_s] = (conv_x, conv_pdf) else: # 对齐x轴(这里简化处理,实际可以用插值) target_x, target_pdf = new_dp[to_s] # 插值到相同的x轴 interp_pdf = np.interp(target_x, conv_x, conv_pdf, left=0, right=0) new_dp[to_s] = (target_x, target_pdf + interp_pdf) dp = new_dp # 绘制终态的总成本分布 x_end, pdf_end = dp['end'] plt.figure(figsize=(8,5)) plt.plot(x_end, pdf_end) plt.title('Total Cost Distribution to End State') plt.xlabel('Total Cost') plt.ylabel('Probability Density') plt.show()
注意事项
- 当状态和转移数量很大时,需要优化离散化的精度和卷积效率,避免内存溢出。
- 对于无限状态或长路径,可以采用迭代收敛的方式,直到分布变化足够小为止。
- 如果成本分布是连续的,离散化的 bins 数量需要权衡精度和计算速度。
内容的提问来源于stack exchange,提问作者JackDaniels
相关产品推荐
相关产品推荐

