我的新博客地址:Hu Haoyu’s Blog,欢迎参观。
计算机产生的大多数随机数都是伪随机数。是按照分布概率产生随机数字的过程,数字在概率分布上满足随机要求,但实际上是计算机通过随机函数模拟产生的。生成的方法包括直接法、逆转法、接受拒绝法等。本篇要介绍的是prd伪随机算法和基于rsa的伪随机算法。
Pseudo Random Distribution
这种伪随机算法在游戏中的应用非常广泛。游戏希望角色间应互相制衡,同时为增加游戏的不确定性,故引入了随机概念,如暴击率、回避率等都是一个随机概率的表现。prd伪随机算法能够尽量使触发事件的情况均匀地分布在多次事件中,从而避免了连续多次的暴击或回避,也可以减少长时间不暴击情况的发生。
实际上Pseudo Random Distribution是来自Warcraft3引擎,同时在dota2中得到了发扬。prd伪随机算法是计算触发角色特殊能力的概率的算法。对于普通的伪随机算法,我们能够发现,每次触发事件的概率都相同。但对于prd伪随机算法而言,每次触发事件的概率却不相同,它会随着暴击事件或非暴击事件的触发而改变。但在均摊概率上来说,却是满足角色能力要求的,也是满足随机概率要求的。
一定程度上prd算法改善了暴击的发生的频次和分布,使其更为均匀,从而保证了游戏的公平性和趣味性。
具体实现
prd的工作机制大致如下:触发事件的概率会随着未触发事件发生的次数增加而增加,直到100%。另一方面,当触发一次事件后(如暴击事件),紧接着下一次动作触发事件的概率会明显地低于平均概率p,这也是为了防止多次触发事件。
实验发现,采用prd伪随机算法和普通的伪随机算法,后者多次连续触发事件的概率高于前者,也就是说,prd算法试验中“极为幸运”或“极为不幸”的事件很少发生。但对于总体而言,二者的均摊概率是相同的。
如未触发事件,每次的增量概率应该是游戏中预先计算好的,保存在一张表中。之所以不在游戏中计算,是因为prd算法获得增量概率的计算量和所需时间要多余普通的随机算法。在Warcraft3中增量概率步长为
5%
,但这对触发概率大于15%
的事件而言是不正确的。对于有些动作是不能出发概率增加的,如对防御塔的攻击。
wiki中给出了prd的计算结果表。
P(T) | P(A) | C | Max N | Most Probable N | Average N | SD | SDt |
---|---|---|---|---|---|---|---|
5% | 5% | 0.00380 | 264 | 16 | 20.00 | 10.30 | 19.53 |
10% | 10% | 0.01475 | 68 | 8 | 10.00 | 5.06 | 9.50 |
… | … | … | … | … | … | … | … |
75% | 63.2% | 0.46134 | 3 | 2 | 1.58 | 0.57 | 0.96 |
80% | 66.7% | 0.50276 | 2 | 1 | 1.50 | 0.5 | 0.87 |
正如上表给出的结果。PT为理论概率,PA为实际均摊概率,C时prd常数(增量概率),Max N是达到100%所需次数,Most Probable N为触发事件最有可能的次数,Average N是触发事件平均次数,SD为N的理论标准差,SDt为普通随机算法的标准差。由此可见,该伪随机算法一定程度上降低了离散程度,使得游戏更为公平。
伪随机与加密算法
网上看到可以用rsa生成伪随机数。命题如下:如何生成1亿个不重复的伪随机数。显然用普通的随机算法效率太低。但仔细想来,生成伪随机数如果不重复的话,就是一个打乱的过程。这就可以用到rsa这种目前被广泛应用的加密算法。
具体的操作步骤如下:
a = (b ^ c) mod (m * n);
(c * d) mod ((m - 1) * (n - 1)) = 1
b = (a ^ d) mod (m * n)
上式中,m、n、c为素数。由第一条和第三条等式可以得出,a和b是一一对应的映射。由此可以由有序的序列A={a1,a2,a3,…,an}派生出随机序列B={b1,b2,b3,…,bn}。其中,m、n、c都是事先确定的常数,它们满足第二条等式,如m=3,n=5,c=3,满足等式(3 * 3) mod (2 * 4) = 1。
不妨对2到9之间的数字生成伪随机数。
2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|
8 | 12 | 4 | 5 | 6 | 13 | 2 | 9 |
对于这种生成不重复伪随机数的方法有几个前提要求。上面的m和n不能够相同,也就是说它们必须是不同的素数。同时,d和(m-1)*(n-1)的最大公因数为1。
参考
本文参考了Pseudo-random distribution以及生成伪随机数的超级算法。
如分析有误,请批评指正,谢谢。