在Go 中创建一组正态分布的数字可以按如下方式完成。
func getNormDistro(x int){
for i := 0; i < x; i++{
fmt.Print(" ",int(normalInverse(80,10)), " ")
}
}
func normalInverse(mu float32, sigma float32)(float32){
return float32(rand.NormFloat64() * float64(sigma) + float64(mu))
}
运行以下命令:
getNormDistro(10)
打印此内容:
86 74 79 94 73 92 66 77 74 78
唯一的问题是分布不一致,并且具有随机性。这意味着生成的曲线可能无法尽可能接近正态分布固化。
如何使一个函数以算法方式尽可能接近正态分布,而输出中没有随机分量?
所以,我知道这是可能的,因为你可以很容易地在 excel 中做到这一点。Excel 具有此函数 =NORMINV(E3,C3,D3(,它将 3 周长出现概率(作为小数(、分布平均值和标准差。此函数返回输入的百分比机会的值。
如果您使用特定平均值和 .5 标准差迭代发生概率百分比,您将获得平均值,如果您的迭代均匀分布在 0% 到 100% 之间,则标准分布将被打包,没有随机分量。
Data Set Mean Standard Deviation % Chance
56.73652126 80 10 0.01
56.73652126 80 10 0.02
61.19206392 80 10 0.03
62.49313929 80 10 0.04
63.55146373 80 10 0.05
64.45226405 80 10 0.06
65.24208972 80 10 0.07
65.9492844 80 10 0.08
66.59244966 80 10 0.09
67.18448434 80 10 0.1
67.7347188 80 10 0.11
68.25013208 80 10 0.12
68.73608871 80 10 0.13
69.19680659 80 10 0.14
69.63566611 80 10 0.15
70.05542117 80 10 0.16
70.45834747 80 10 0.17
70.84634912 80 10 0.18
71.22103705 80 10 0.19
71.58378766 80 10 0.2
71.93578753 80 10 0.21
72.27806786 80 10 0.22
72.61153151 80 10 0.23
72.93697437 80 10 0.24
73.2551025 80 10 0.25
73.56654595 80 10 0.26
73.87187009 80 10 0.27
74.17158493 80 10 0.28
74.4661528 80 10 0.29
74.75599487 80 10 0.3
75.04149653 80 10 0.31
75.32301201 80 10 0.32
75.60086834 80 10 0.33
75.87536871 80 10 0.34
76.14679534 80 10 0.35
76.41541207 80 10 0.36
76.68146654 80 10 0.37
76.94519212 80 10 0.38
77.20680966 80 10 0.39
77.46652897 80 10 0.4
77.72455023 80 10 0.41
77.98106521 80 10 0.42
78.23625835 80 10 0.43
78.49030785 80 10 0.44
78.74338653 80 10 0.45
78.99566279 80 10 0.46
79.24730138 80 10 0.47
79.49846417 80 10 0.48
79.74931092 80 10 0.49
80 80 10 0.5
80.25068908 80 10 0.51
80.50153583 80 10 0.52
80.75269862 80 10 0.53
81.00433721 80 10 0.54
81.25661347 80 10 0.55
81.50969215 80 10 0.56
81.76374165 80 10 0.57
82.01893479 80 10 0.58
82.27544977 80 10 0.59
82.53347103 80 10 0.6
82.79319034 80 10 0.61
83.05480788 80 10 0.62
83.31853346 80 10 0.63
83.58458793 80 10 0.64
83.85320466 80 10 0.65
84.12463129 80 10 0.66
84.39913166 80 10 0.67
84.67698799 80 10 0.68
84.95850347 80 10 0.69
85.24400513 80 10 0.7
85.5338472 80 10 0.71
85.82841507 80 10 0.72
86.12812991 80 10 0.73
86.43345405 80 10 0.74
86.7448975 80 10 0.75
87.06302563 80 10 0.76
87.38846849 80 10 0.77
87.72193214 80 10 0.78
88.06421247 80 10 0.79
88.41621234 80 10 0.8
88.77896295 80 10 0.81
89.15365088 80 10 0.82
89.54165253 80 10 0.83
89.94457883 80 10 0.84
90.36433389 80 10 0.85
90.80319341 80 10 0.86
91.26391129 80 10 0.87
91.74986792 80 10 0.88
92.2652812 80 10 0.89
92.81551566 80 10 0.9
93.40755034 80 10 0.91
94.0507156 80 10 0.92
94.75791028 80 10 0.93
95.54773595 80 10 0.94
96.44853627 80 10 0.95
97.50686071 80 10 0.96
98.80793608 80 10 0.97
100.5374891 80 10 0.98
103.2634787 80 10 0.99
110.9023231 80 10 0.999
117.1901649 80 10 0.9999
122.6489079 80 10 0.99999
127.5342431 80 10 0.999999
49.09767694 80 10 0.001
42.80983515 80 10 0.0001
37.35109206 80 10 0.00001
32.46575691 80 10 0.000001
28.00662418 80 10 0.0000001
23.87998756 80 10 0.00000001
随机分布的数学描述通常是通过其概率分布函数。对于像正态分布这样的连续分布,它要么表示为概率密度函数(您可能知道的钟形曲线(,要么表示为其积分的累积分布函数。所以也许你想计算这个函数。
另一方面,您在实现和引用的 Excel 函数中使用术语逆表明您实际上正在寻找逆运算:给定概率,找到累积概率函数达到该值的值。这称为给定概率的分位数。
不幸的是,正态分布有一个非常复杂的公式,很难计算。它的分位数函数并不容易。因此,与其尝试正确计算,我建议您使用一些提供该功能的库。一些网络搜索表明了这一点:
https://godoc.org/gonum.org/v1/gonum/stat/distuv#Normal.Quantile
func (n Normal) Quantile(p float64) float64
分位数返回累积概率分布的反函数。
查看底层实现表明我不想自己解决这个问题。另请注意,这将是一个近似值(看起来像 Padé 近似值的分段组合(,乍一看我没有看到任何提到误差边界。其他库可能有更好的接近度或更好的保证。
如果您确实想要一个遵循此分布的数字数组,请选择与 (0,1( 等距的概率(这可能意味着从 1/(n+1( 到n/(n+1( 或 1/(2 n(、3/(2n(、...(2n−1(/(2n( 取决于应用或口味(并计算这些分位数。如果你真的想要整数,你可以在之后四舍五入。但是您可能还想检查连续分布是否适合您,或者使用离散分布(如二项分布(是否更好。