4、随机数与概率分布:均匀分布、正态分布、指数分布生成方法

做仿真这么多年,我越来越觉得随机数这东西,就像仿真系统的「味精」——放少了没味道,放多了又容易串味。很多刚入行的朋友以为随机数就是随便取个数,其实不然。你想想看,如果仿真里的客户到达时间全是均匀的,那跟现实世界差得也太远了。

今天咱们就聊聊三种最常用的分布:均匀分布、正态分布、指数分布。我会结合我踩过的坑,把生成方法讲透。

4.1 均匀分布:最基础的随机数

均匀分布是所有随机数的「祖宗」。说白了,就是在某个区间内,每个数出现的概率都一样。

数学定义:在区间 [a, b] 上,概率密度函数为 f(x) = 1/(b-a)。

生成方法:几乎所有编程语言都内置了均匀随机数生成器。比如 Python 的 random.uniform(a, b)

核心要点:均匀分布常用于模拟「无偏」的随机事件,比如骰子点数、抽奖等。

import random

# 生成 [0, 1) 之间的均匀随机数
r = random.random()
print(f"随机数: {r}")

# 生成 [10, 20] 之间的均匀随机数
r2 = random.uniform(10, 20)
print(f"区间随机数: {r2}")

我的经验:我在做物流仿真时,曾用均匀分布模拟仓库拣货时间。结果发现实际数据偏差很大——因为工人会疲劳,速度会下降。均匀分布只适合「稳定状态」下的随机过程。

4.2 正态分布:自然界最常见的分布

正态分布,也叫高斯分布。你想想看,人的身高、考试成绩、测量误差……几乎都服从正态分布。为什么会这样?因为中心极限定理告诉我们,大量独立随机变量的和会趋近正态分布。

数学定义:概率密度函数为 f(x) = (1/(σ√(2π))) * e^(-(x-μ)²/(2σ²)),其中 μ 是均值,σ 是标准差。

生成方法:Python 的 random.gauss(mu, sigma)numpy.random.normal(mu, sigma)

import random
import math

# Box-Muller 变换:从均匀分布生成正态分布
def box_muller():
    u1 = random.random()
    u2 = random.random()
    z0 = math.sqrt(-2 * math.log(u1)) * math.cos(2 * math.pi * u2)
    z1 = math.sqrt(-2 * math.log(u1)) * math.sin(2 * math.pi * u2)
    return z0, z1

# 生成均值为 100,标准差为 15 的正态分布
mu, sigma = 100, 15
z, _ = box_muller()
x = mu + sigma * z
print(f"正态分布样本: {x:.2f}")

# 直接用库函数
import numpy as np
samples = np.random.normal(mu, sigma, 1000)
print(f"前5个样本: {samples[:5]}")

避坑指南:我曾经在仿真中直接用正态分布模拟「响应时间」,结果出现了负数——因为正态分布理论上可以取任何值。对于时间、长度等非负量,建议用截断正态分布或对数正态分布。

4.3 指数分布:描述「等待时间」的利器

指数分布是仿真里最常用的分布之一。它描述的是「事件发生的时间间隔」。比如:电话呼叫的间隔、机器故障的间隔、顾客到达的间隔。

数学定义:概率密度函数为 f(x) = λe^(-λx),x ≥ 0。其中 λ 是事件发生率(单位时间内事件发生的次数)。

关键性质:无记忆性。也就是说,已经等了多久,不影响还要等多久。这一点在排队论里特别重要。

import random
import math

# 逆变换法:从均匀分布生成指数分布
def exponential(lambda_rate):
    u = random.random()
    return -math.log(1 - u) / lambda_rate

# 生成事件率为 0.5 的指数分布(平均间隔 2 秒)
lambda_rate = 0.5
intervals = [exponential(lambda_rate) for _ in range(10)]
print(f"前10个时间间隔: {[f'{x:.2f}' for x in intervals]}")

# 用库函数
import numpy as np
samples = np.random.exponential(1/lambda_rate, 1000)
print(f"平均间隔: {np.mean(samples):.2f} 秒")

实际应用:我在做呼叫中心仿真时,用指数分布模拟客户来电间隔。λ 取 0.2(平均每5秒一个电话),配合正态分布的服务时长,效果非常接近真实数据。

4.4 三种分布的对比与选择

分布类型 适用场景 参数 取值范围 典型例子
均匀分布 无偏随机、等概率事件 a(下限)、b(上限) [a, b] 骰子点数、随机抽样
正态分布 自然现象、测量误差 μ(均值)、σ(标准差) (-∞, +∞) 身高、考试成绩
指数分布 等待时间、事件间隔 λ(事件率) [0, +∞) 电话间隔、故障间隔

4.5 知识体系图

下面这张图展示了三种分布的核心关系和应用场景,我建议你保存下来,做仿真时对照着看。

随机数与概率分布知识体系 随机数生成 均匀分布 正态分布 指数分布 骰子、抽样、随机位置 身高、误差、自然现象 等待时间、事件间隔 random.uniform(a, b) random.gauss(mu, sigma) 逆变换法 / numpy 核心原则:根据实际数据选择分布,不要盲目套用

4.6 实战建议

  • 先看数据:拿到真实数据后,先画直方图,看看形状像哪种分布。
  • 参数估计:用最大似然估计或矩估计来拟合参数。
  • 验证:用 Kolmogorov-Smirnov 检验或卡方检验来验证拟合效果。
  • 注意边界:正态分布可能产生负数,指数分布适合无记忆场景。

我的习惯:每次做仿真前,我都会先跑 10000 个随机数,画个分布图看看。如果形状跟预期不符,赶紧检查参数。这一步能省掉后面很多调试时间。

好了,关于随机数与概率分布,今天就聊到这儿。记住一句话:仿真不是猜谜,随机数也不是随便数。选对分布,你的仿真就成功了一半。


公众号:蓝海资料掘金营,微信deep3321