using System; namespace TBL.CSharp.Utilities.Random.Generator { /// /// 高斯随机数发生器 /// 需要正态分布的随机数序列时,适用此设施 /// 内部使用 作为辅助熵 /// public class GaussianGenerator : IRandom { /// /// 种子值 /// private int _seed; /// /// 辅助熵 /// private readonly SimpleGenerator _random; /// /// 已经生成的随机数计数 /// private long _numberGenerated; /// /// 下一个高斯随机数 /// private double _nextGaussian; /// /// 是否使用末项 /// private bool _useLast = true; /// /// 从种子构造 /// /// 种子值 public GaussianGenerator(int seed) { _seed = seed; _random = new SimpleGenerator(seed); } public int NextRaw() { _numberGenerated++; const double num1 = 3.5; var num2 = (int)BoxMuller(0 + int.MaxValue / 2.0, int.MaxValue / 2.0 / num1); return num2; } public Seed DumpSeed() => new Seed(_seed, _numberGenerated); public void RestoreBySeed(Seed seed) { _seed = seed.SeedValue; _random.RestoreBySeed(new SimpleGenerator.Seed(seed.SeedValue)); _numberGenerated = 0L; _nextGaussian = 0.0; _useLast = true; for (long index = 0; index < seed.NumberGenerated; ++index) this.Next(); } /// /// Box Muller 算法 /// private double BoxMuller() { if (_useLast) { _useLast = false; return _nextGaussian; } double num1; double num2; double d; do { num1 = 2.0 * _random.NextDouble() - 1.0; num2 = 2.0 * _random.NextDouble() - 1.0; d = num1 * num1 + num2 * num2; } while (d >= 1.0 || d == 0.0); double num3 = Math.Sqrt(-2.0 * Math.Log(d) / d); _nextGaussian = num2 * num3; _useLast = true; return num1 * num3; } /// /// Box Muller 算法 /// private double BoxMuller(double mean, double standardDeviation) => mean + BoxMuller() * standardDeviation; /// /// 种子 /// public readonly struct Seed { /// /// 种子值 /// public readonly int SeedValue; /// /// 已经生成的随机数计数 /// public readonly long NumberGenerated; /// /// 构造 /// public Seed(int seed, long numberGenerated) { SeedValue = seed; NumberGenerated = numberGenerated; } } } }