/// <summary>
/// 正态分布(高斯分布)
/// </summary>
public class Gaussian
{
public const int MIU = 0;
public const int SIGMA = 1;
private readonly Random rnd;
public Gaussian()
{
rnd = new Random((int)DateTime.Now.Ticks & 0xFFFFFF);
}
/// <summary>
/// 获取一个指定范围内的标准正态分布随机数
/// </summary>
/// <param name="min">最小值(返回的值可包含最小值)</param>
/// <param name="max">最大值(返回的值可包含最大值)</param>
/// <returns></returns>
public double Random(double min, double max) => Random2(min, max)[0];
/// <summary>
/// 获取一个或两个指定范围内的标准正态分布随机数
/// </summary>
/// <param name="min">最小值(返回的值可包含最小值)</param>
/// <param name="max">最大值(返回的值可包含最大值)</param>
/// <returns></returns>
public double[] Random2(double min, double max)
{
if (max <= min) return new[] { min };
var list = new List<double>();
while (list.Count == 0)
{
foreach (var normal in GetValue(rnd, SIGMA, MIU))
{
var value = ConvertValue(normal, min, max);
if (value >= min && value <= max)
{
list.Add(value);
}
}
}
return list.ToArray();
}
/// <summary>
/// 转换为指定范围内的值。返回结果可能会超出范围为,因为大约99.7%概率在范围内(3σ原则)。
/// </summary>
/// <param name="normal">正态分布数</param>
/// <param name="min">最小值</param>
/// <param name="max">最大值</param>
/// <returns></returns>
private static double ConvertValue(double normal, double min, double max)
{
var median = (max - min) / 2.0;
return (normal * median / 3) + min + median;
}
/// <summary>
/// 获取两个正态分布随机数
/// </summary>
/// <param name="random">生成随机数的对象</param>
/// <param name="deviation">标准差σ</param>
/// <param name="expected">期望值μ</param>
/// <returns></returns>
public static double[] GetValue(Random random, double deviation, double expected)
{
double x, y, s;
do
{
x = 2 * random.NextDouble() - 1;
y = 2 * random.NextDouble() - 1;
s = x * x + y * y;
}
while (s > 1 || s == 0);
double multi = Math.Sqrt(-2 * Math.Log(s) / s);
//return new double[] { Math.Round(x * multi, 2) * deviation + expected, Math.Round(y * multi, 2) * deviation + expected };
return new double[] { x * multi * deviation + expected, y * multi * deviation + expected };
}
}