gamemaker吧 关注:13,603贴子:94,722
  • 9回复贴,共1

[搬运][研究成果]关于随机数的分布

只看楼主收藏回复

应邀请搬运一下,反正原文也是咱写的。
整个研究的起源,大概是贴吧里那个三段棍子拼三角形的问题吧。
忽略掉一些无关的回忆,开始正题。现在大多数的随机算法应该都在努力保证计算结果分布比较均匀。比如GM里生成无数多次的random(1),其中0.5以上和0.5以下的结果都会很接近50%,0.8以下的数字大约占总数的80%。如果我们需要一些“不均匀”的分布情况,就只好自己手动解决了。
研究第一天:让随机数变得不均匀的算法
研究结果大概可以用下边的分布图来表示,布图是在宽度600的容器里进行随机打点的结果,当任意点累计到200个时停止累计。用于观察不同随机数处理的分布结果:

下面说明的伪代码里有一个范围校正(),作用是将输入数字从现有范围线性变更到指定范围,如random(60)的范围是0-60,如果需要的实际范围是0-600,则需要将结果X10。将mini-maxi范围的i变更到mino-maxo范围输出o,计算式为o=i*(maxo-mino)/(maxi-mini)+maxo。大多数情况下这个算式可以化简,最终是o=a*i+b的样子。
第一个蓝色的图,表示的是最基础的随机。不经过任何处理直接累计结果,可以看到整体分布比较均匀,局部范围存在跳动。
第二个绿色的图,表示1-2平方分布。伪代码是 范围校正(平方(random(1)+1)) ,可以看到分布有向左偏移的趋势。
第二个天蓝的图,表示1-9平方分布。伪代码是 范围校正(平方(random(8)+1)) ,可以看到分布有更加明显向左偏移的趋势。
第四个红色的图,表示平方根的分布。伪代码是 范围校正(平方根(random(x))) ,可以看到分布有向右偏移的趋势,且分布目测比较均匀。尝试更换x的值,在完成范围校正后图形没发现显著区别。
第五个粉色的图,表示0-π范围取正弦的分布。伪代码是 范围校正(sin(random(pi))),图形在最大值附近堆积严重。
第六个黄色的图,表示0-(π/2-0.1)范围取正弦的分布。伪代码是 范围校正(sin(random(pi/2-0.1))),缓解了图形在右侧堆积的情况,左侧范围的分布量有所增加。
第七个白色的图,表示(0.1-π/2)-(π/2-0.1)范围取正弦的分布。伪代码是 范围校正(sin(random(pi-0.2-pi/2+0.1)),差不多是6号图对称了一下,变成了两侧分布。
反正,类似的代码大家能想到的应该比我多吧,像是“生成数量500的弹幕,要上方密集下方疏松的结构”这样也能做到了。
最后再补充一句,如果是生成圆形弹幕,角度和半径都均匀随机的结果就是内圈比外圈弹幕密集,详细的结果,嗯,继续看就是了,反正搬运的话可以扔进一个楼里。
=============原楼层的分隔线=============
圆形区域分布
如果角度和半径都均匀随机,点分布会显得中间比较集中……想想也是啊,分布在半径1的小圆里和分布在半径99-100的圆环里的概率相等,前者的面积明显小于后者。
由于是二维分布,测试点的方式已经改成了在纯黑色的背景上打逐渐变白的像素点,直到有一个像素达到白色(255)为止。

前两个图是角度/半径都均匀分布的结果,其中半径排除了距离圆心较近的区域。可以看到测试结果和之前的预估一致。
第三个图是将随机结果进行了开平方处理,结果表明分布情况比较接近于均匀分布。
第四个图比较有意思,是尝试“球形表面均匀分布”的结果。

首先把球放在一个对应圆柱里,圆柱的圆半径和球半径一致,高和球直径一致。据可靠消息,球面上任意两纬度之间的面积和对应圆柱位置的面积相等,这样球面上的点过“地轴”做垂线和对应圆柱相交的点就可以认为是“配对点”。结果就是球面上的分布问题就完全转移到了圆柱面上,而圆柱面展开以后又是简单的长方形。反正按长方形的样子均布一下,再通过一定算法对应到球面上就是啦。当然,这次的分布图只有X和Y,Z轴被忽略掉了。
==========搬运的后话=========
那个球面分布的图,后来被改装了一下,做成爆炸效果用在ACT游戏里了,之前发的那个带动画的2048里边用的也是这个。


IP属地:北京本楼含有高级字体1楼2015-01-31 15:42回复
    虽不明,但觉厉。
    支持学术研究,赞!


    IP属地:河南2楼2015-01-31 19:13
    回复
      好东西,mc里不同深度的出矿率可以用这个来代替


      IP属地:陕西来自Android客户端3楼2015-02-01 09:24
      回复
        太长 而且听不懂 不过觉得很厉害


        6楼2017-03-26 06:44
        回复
          感觉random产生的不是真的随机数,而是从0开始每一步加最小单位值。也就是说random产生的值和时间有关。不知道这软件实际是不是这样。


          IP属地:湖北来自Android客户端7楼2024-01-02 23:40
          收起回复