跳至主要內容

使用C#产生各种随机数(一)

MonoLogueChiUnity大约 3 分钟

在很多时候,我们需要用到各种各样的随机数,比如平均分布正态分布泊松分布指数分布等等。

在网上找了很多资料,终于集齐了一套,这里做一下笔记,希望以后再用的时候能记起来。

因为篇幅比较长,本篇文章先介绍一下平均分布和正态分布,剩下的内容留给下一篇文章。

平均分布

平均分布的随机数产生是最容易的,我们可以直接使用.netopen in new window 的随机数产生类 System.Random 产生符合平均分布的随机数。
当然,Unity 重也可以使用 UnityEngine.Random 产生随机数。

原理

这个原理的话,就是伪随机数产生的原理,首先需要给定一个随机因子,然后以这个随机因子为基础,进行一系列的运算,然后产生一个伪随机数,如果不给定随机因子,就会使用当前的系统时间进行计算。

演示

using System;

namespace RandomDemo
{
    public class U
    {
        Random rand = new Random();

        public int U0(int min ,int max)
        {
            var a = rand.Next(min ,max);
            return(a);
        }
    }
}

使用上面的代码,不指定随机因子产生随机数,然后使用 for 循环产生 9000 个 -50 - 50 之间的随机数;

using System;

namespace RandomDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            U u = new U();

            for (int i = 0; i < 9000; i++)
            {
                var a = u.U0(-50, 50);
                Console.WriteLine(a);
            }

            Console.ReadKey();
        }
    }
}

接下来使用 Origin 统计分布频度,作图:

可以看出,基本符合平均分布特点(样品越多,统计结果越准确,有兴趣的话可以弄 100K 个样本试试看有什么效果)。

正态分布

若随机变量 X 服从一个数学期望为 μ、方差为σ^2的正态分布,记为N(μ,σ^2)。其概率密度函数为正态分布的期望值 μ 决定了其位置,其标准差 σ 决定了分布的幅度。当 μ = 0,σ = 1 时的正态分布是标准正态分布。

原理

极坐标形式

假设 u 和 v 是 [-1, 1] 均匀分布的随机量,且 u 和 v 彼此独立,令:

那么随机数 z0 和 z1 可以按照如下公式产生,结果是 z0 和 z1 服从 N(0,1)的随机数,且 z0 和 z1 彼此独立;
m6tOY.png
m66ei.png
有兴趣的同学可以看一下这一段 原文链接open in new window

演示

using System;

namespace RandomDemo
{
    public class N
    {
        Random rand = new Random();

        //标准正态分布
        public double Normal()
        {
            double s = 0, u = 0, v = 0;
            while (s > 1 || s == 0)
            {
                u = rand.NextDouble() * 2 - 1;
                v = rand.NextDouble() * 2 - 1;

                s = u * u + v * v;
            }

            var z = Math.Sqrt(-2 * Math.Log(s) / s) * u;
            return (z);
        }

        //符合要求的正态分布随机数
        public double RandomNormal(double miu ,double sigma)
        {
            var z = Normal() * sigma + miu;
            return (z);
        }
    }
}

同样,我们使用 9000 个随机数验证随机数分布规律

using System;

namespace RandomDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            N n = new N();

            for (int i = 0; i < 9000; i++)
            {
                var z = n.RandomNormal(0, 10);
                Console.WriteLine(z);
            }

            Console.ReadKey();
        }
    }
}

使用 Origin 作图,并使用高斯方程拟合曲线可以得到下图:

从图中我们可以看出,分布中心 μ 接近 0,而 σ 接近 10(9.885),基本符合我们的预期。

下期预告

以后有时间会接着介绍泊松分布和指数分布随机数的产生方法。