我有一个非空整数区间 [a; b)。我想生成一个随机的非空整数子区间 [c; d)(其中 a <= c 和 d <= b)。 [c; d) 区间必须是均匀分布的,即 [a; 中的每个点; b) 必须同样有可能最终出现 [c; d).
我尝试从 [a; 生成均匀分布的 c; b - 1),然后从 [c + 1; 均匀分布 d; b),像这样:
a = -100
b = 100
N = 10000
cs = np.random.randint(a, b - 1, N)
ds = np.random.randint(cs + 1, b)
但是当测量每个点最终被采样的频率时,分布显然是不均匀的:
import numpy as np
import matplotlib.pyplot as plt
hist = np.zeros(b - a, int)
for c, d in zip(cs, ds):
hist[c - a:d - a] += 1
plt.plot(np.arange(a, b), hist)
plt.show()
如何正确执行此操作?
创建
cs
和 ds
的方式导致了分布混乱,因为它增加了偏差。
相反,通过随机选择起点和终点来生成子区间,确保每个子区间的可能性相同。对于每个起点
c
,d
内的任何终点 [c+1, b]
都是可能的,从而有效地随机化子区间选择
实现这一目标的更干净的方法可能看起来像
import numpy as np
import matplotlib.pyplot as plt
a, b, N = -100, 100, 10000
# random start and end points for subintervals, ensuring they are sorted
starts_ends = np.sort(np.random.randint(a, b, (N, 2)), axis=1)
# Extract start (c) and end (d) points
cs, ds = starts_ends[:,0], starts_ends[:,1]
# store frequency counts
hist = np.zeros(b - a)
# count occurrences within each subinterval
for c, d in zip(cs, ds):
hist[c-a:d-a] += 1
plt.plot(np.arange(a, b), hist)
plt.title("Points in Selected Subintervals")
plt.show()