随机数真的“随机”吗?

51 阅读4分钟

之前做过一个抽奖项目,然后使用到了生成随机数然后根据随机数落到哪个区间表示中奖类型。

然后就想好好研究一下随机数的问题

Java 中的随机数

Java 中的随机数生成

Random random = new Random();

Random类使用了**线性同余生成器(Linear Congruential Generator,LCG)**算法。其核心公式为:

Xₙ₊₁ = (a * Xₙ + c) mod m
  • Xₙ:第n个随机数
  • a:乘数
  • c:增量
  • m:模

这里a、c和m的值是固定的,X0 就是 设置的种子值,种子值默认是System.nanoTime(微秒级别)(weim)。

给定初始种子(seed),通过上述公式可以生成一系列看似随机的数值。但由于算法是确定性的,如果知道种子值,就可以预测整个序列。

另外,如果多个线程几乎同时创建Random对象,可能得到相似的种子值,这里的“同时”大概在毫秒级别。

当然 random 在正常使用起来没有问题,一些改进的比如ThreadLocalRandom:为每个线程提供独立的生成器。

真假随机数

真正的随机数是使用物理现象产生的:比如掷钱币、骰子、转轮、使用电子元件的噪音、核裂变等等,这样的随机数发生器叫做物理性随机数发生器,它们的缺点是技术要求比较高。

(比如 SecureRandom 基于操作系统提供的环境熵(如鼠标移动、键盘敲击、硬件噪声)生成真正的随机数 , 随机数API,如Random.org,其随机数基于大气噪声 ,突然想到还可以根据股市,hhhhh )

而计算机中的随机函数是按照一定算法模拟产生的,其结果是确定的,是可见的。

伪随机数其实是有规律的。只不过这个规律周期比较长,但还是可以预测的。

所以敢网络赌博的人,肯定没有思考过这个事儿。

游戏里面的暴击率真的是随机的吗?

显然不是!

游戏数值设计者在大多数游戏里做的概率设计是伪随机

比如20%的暴击率,理论上讲每一次攻击触发暴击都是固定的几率20%,每一次攻击的暴击率是独立且固定的,并不受攻击次数和之前攻击效果的影响。

理论上讲次攻击都不暴击的概率为 0.8^5 = 0.32768,看起来都挺大的,但是 5 次都没暴击,你受得了,而且 10 次都没暴击的概率就 0.1 左右,也不小,要出现了得疯掉。

所以玩家存在另一种理解,玩家期待的是 5次攻击必定出现1次暴击,更宽泛的一点说,玩家会认为在37(一般46为佳)次的过程中必定会发生一次暴击。对于数值设计者而言,并不希望玩家能够在20%的暴击率下,获得较高概率的连续两次暴击,同时也不希望出现连续10次不发生暴击的情况。

物理随机真的随机吗?

当然这是一个哲学命题啊

大刘的《镜子》中讲了这样一个故事:有一个人发明了这样一个机器,给奇点调出了正确的参数,然后就调出了一个光速为 30w 的宇宙——也就是他模拟出了地球,这个机器可以知道所有的过去以及当下。后来这个机器用于防止犯罪,后来抓紧用于治理贪污,最后……人类 文明 灭亡了!

当然这涉及到量子力学和哲学思辨了, 量子力学的核心观点之一是,粒子在被测量之前,其状态是不可预知的 。

人有自我意识吗?

人的命运是随机的吗?

换言之,人的命运在出生之后就被安排好了吗?

这让我想到另外一个故事,最初研究 的科学家,为了让 ai 学会人的语言,加了无数条规则,但是最后是死路一条,后来方向变为用统计学,用语料堆积,用概率预测。

所以换言之,人生不是命定的,但是是有概率的,符合统计学,这里的概率指社会规则吧,穷人孩子相比难有出息,矮子很难打好篮球。

但是,人存在的意义就是生活的概率之中,同时想突破概率。