生成4个和为100的随机数的实现问题
生成4个和为100的随机数的实现问题
嘿,我完全懂你遇到的这个困扰!你一开始想的分步生成随机数的思路,确实存在一个核心问题——按照你写的步骤,最后四个数的总和大概率小于100,没法保证刚好等于目标值,对吧?
先帮你梳理下你原来的思路问题:
- 第一步生成x:$x \sim \text{Uniform}(0, 100)$
- 第二步生成y:$y \sim \text{Uniform}(0, 100 - x)$
- 第三步生成z:$z \sim \text{Uniform}(0, 100 - x - y)$
- 第四步你写的是生成w服从Uniform(0, 100 - x - y - z),这就导致w只是取了剩余值里的一部分,自然总和$x+y+z+w \leq 100$,没法保证等于100。
其实如果只是想让总和刚好为100,你可以把最后一步改成直接让$w = 100 - x - y - z$,这样总和就达标了,但这种方法有个弊端:生成的四个数分布是有偏的——x的期望是25,但y、z、w的期望会依次变小,因为每一步都是从剩余的数值里随机取,不是均匀分布在所有“和为100的四元组”空间里的。
如果想要生成均匀分布在所有满足$x+y+z+w=100$且$x,y,z,w \geq 0$的四元组,给你两个实用的R实现方法:
方法一:标准化法
先生成四个任意非负随机数,再通过标准化把总和调整到100,代码很简单:
# 生成4个0到1之间的均匀随机数 raw_nums <- runif(4, 0, 1) # 标准化后让总和为100 target_nums <- raw_nums / sum(raw_nums) * 100
这种方法的好处是代码简洁,不过如果你的随机数生成源换了(比如用正态分布),也能适配,只要最后标准化就行。
方法二:间隔截断法
这种方法能保证生成的数严格均匀分布在目标单纯形上,思路是用三个随机分割点把0-100的区间切成四段,每段的长度就是我们要的数:
# 生成3个0到100之间的随机数,然后排序 cut_points <- sort(runif(3, 0, 100)) # 计算每一段的长度,得到四个和为100的数 target_nums <- c( cut_points[1], cut_points[2] - cut_points[1], cut_points[3] - cut_points[2], 100 - cut_points[3] )
这个方法生成的数,每个位置的数值期望都是25,分布更均匀,适合对分布均匀性有要求的场景。
备注:内容来源于stack exchange,提问作者farrow90
相关产品推荐
相关产品推荐

