关于随机数不得不说的一个方法

随机数,接触程序时就会接触到他,第一次知道随机数隐约记得是和同学在讨论彩票摇奖时知道的,现在看着自己那一把厚厚的彩票就知道当时有多天真了,天真的以为那玩意真随机。好了,言归正传。

几乎我接触过的每一种语言都提供产生随机数的系统方法,我平时用的时候直接拉来用了,今天突然看见群里有人在问,就想着那就研究到底,看看random到底是个什么鬼。

产生随机数的方法:


Random属于system下的类,想仔细研究,那就F12戳进去,看看他都有什么方法。

Next()方法用来返回一个随机数。同样的代码你执行和我的结果很可能不一样,而且我多次运行的结果也很可能不一样,这就是随机数。

1、不是bugbug

当我想使用上面的方法生成多个随机数时,我自然而然的想到了for循环,于是我就循环一百次,生成100个随机数,但结果让我有点卵碎。

<pre name="code" class="csharp">if (Input.GetKeyDown(KeyCode.T))
        {
            for (int i = 0; i < 100; i++)
            {
                System.Random rand = new System.Random();
                Debug.Log("随机数 = " + rand.Next());
            }
        }


 

你会发现,出现了大量的重复数字。这还真是见了鬼了。于是我想着rand就是个对象,为什么要每次去实例化,看网上说可以把实例化的代码放在for循环外边,试了试:

 if (Input.GetKeyDown(KeyCode.T))
        {
            System.Random rand = new System.Random();
            for (int i = 0; i < 100; i++)
            {
                Debug.Log("随机数 = " + rand.Next());
            }
        }


还真欧克了

 

2、Why出现重复的现象:

这得扯一扯计算机生成随机数的原理了,隐约记得之前了解过“随机种子”的概念,于是百度了下,原理是生成随机数的算法有很多种,最简单也是最常用的就是 "线性同余法":  n+1个数=(n个数*29+37) % 1000而“n个数”就称之为随机种子,而重复的根本原因就是默认的随机种子是CPU时钟,现在硬件这么发达,一微妙执行几遍函数都不是问题,所以同一时间段,出现多个重复的随机数也就能理解了。我用代码解释一下公式吧,MyJiLeiRandom自定义的一个功能极其鸡肋的生成随机数的类,你调用Next()就会给你生成鸡肋的随机数

public class MyJiLeiRandom
{
    private int seed = 2;
    public int Next()
    {
        int next = (seed * 29 + 37) % 1000;
        seed = next;
        return next; 
    }
}


他的确看起来是随机的:

 

那我们平时怎么让这个鸡肋的随机数真的很随机呢,其实有很多办法,比如让随机种子等于游戏自打开以来运行的时长、当前用户鼠标在屏幕上的坐标、设置本机处理器ID+启动时长-鼠标坐标.x*鼠标坐标.y。各种方法,就怕你把自己也搞随机了。

用场景加载时长来作为“随机种子”,来产生看似“真正”的随机数。

 if (Input.GetKeyDown(KeyCode.Y))
        {
            MyJiLeiRandom myRand = new MyJiLeiRandom();
            myRand.seed = (int)Time.timeSinceLevelLoad * Screen.currentResolution.height;
            
            for (int i = 0; i < 100; i++)
            {
                Debug.Log("鸡肋类随机数 = " + myRand.Next());
            }
        }


关于真随机数,看过一个帖子,它确实生成了,它主要依据当前进程Id、当前线程Id、系统启动后的TickCount、当前时间、QueryPerformanceCounter返回的高性能计数器值、用户名、计算机名、CPU计数器的值等等来计算。不过一般的项目上确实用不到,如果要用,可自行百度。但万变不离其宗,无非是把“随机种子”搞的几乎不可能重复。

 

 

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值