无论是采用九宫模拟还是八卦模拟,产生随机数都会遇到一个问题,即在9或8上不能平均分布,比如产生的随机数范围是0~65535,一共65536个数,而6+5+5+3+6 = 25,2+5=7,余下为7,这会导致生成的随机数分布概率并不均等,所以它们无法满足在9的空间上能够平均分布,这是不符合自然现状的。如果是对于8来说,已知65536为2的16次方,而2的15次方是可以被8整除的,所以分布下来就多了2个,同样会导致在8的空间分布上不平均。
有一种思路是取一个足够大的数,把误差降到最低,比如取值范围为2的64次方,那么多出来的2个不平均分布,只占1/264 的比重影响,可以说是微乎极微。
不过这样始终让人感觉不完美,所以为了追求完美,完全可以改进一下。
因为通常用八卦时不一定要用九宫,用九宫时一定要用到八卦,所以这个问题并不难解决。
需要构造出一个方法,让它都能整除,即存在一个数S
S%8=0 S%9=0 并且 S =2N (n=0,1,2,3,4….)
但这个是没有解的,所以是不现实的,那么就把问题改一下:
如果是2某个次方加上一个数满足这个条件的话,那就会大大减低计算量。
于是搜了一下解集,发现如下可以满足条件:
式 次方值
2^6+8 64
2^12+8 4096
2^18+8 262144
2^24+8 16777216
2^30+8 1073741824
2^36+8 68719476736
2^42+8 4398046511104
2^48+8 281474976710656
2^54+8 18014398509481984
2^60+8 1152921504606846976
最小的取值可以是2的6次方,而加上一个8后,64+8=72,它就可以除以9了。
那么这个应该如何进行?计算机是二进制的,这个是非常美妙的事情,因为这意味着它的随机数发生器,无论要表示什么数字,是由低位到高位来表达的。
比如1~8的表达,是000,111这样的数字,而更进一步简化来说,如果只需要取八卦起卦,直接用随机数,取最低三位即可表达(实际表达为0~7)。
如果取1~9来表达,必须要用64+8+72的表达方式,之所以能够这样,是因为计算机是二进制,无论它产生什么样的随机数,表达总是从低位到高位来的,已知72的二进制是1001000,然而按位操作是很难取出来的,所以最好的办法是通过位来取组合值,这样运算不但快,而且能分布均匀,先取出来0~7然后再取出来0~63,然后加起来除以9取余,这样分布就完全一样了。
可以先取最低6位值,然后右移6位,再取三位,把它们相加,这样就能在一个随机数上得到0~72的值。
------------------
更新一下,以上移位操作取数相加不可行,因为会变成正态分布….
Leave a Reply