设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 1953|回复: 1
打印 上一主题 下一主题

[RMXP发布] 随机数发生器Mersenne Twister 照抄版

[复制链接]

Lv1.梦旅人

梦石
0
星屑
50
在线时间
182 小时
注册时间
2012-2-11
帖子
233
跳转到指定楼层
1
发表于 2012-11-8 14:24:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
本帖最后由 viktor 于 2012-11-8 14:29 编辑

嗯……其实ruby1.7以上的srand/rand函数本身就是用的mersenne twister产生的强随机数
其实ruby1.9自带了Random类,但是XP用的ruby1.81没有

总之 反正照着标准C程序mt19937ar.c抄了一份ruby的,可以制定随机数种子 和初始向量的随机数产生器。
用法
mt = MT19937.new(seed)    # seed是随机数种子
iv = [123, 456, 789, 1234, 5678] ¥ iv是初始向量,想填几个数字都行,自由发挥
mt.init_array iv # 可以在用种子初始化的基础上,再定义初始向量,增强随机性

随机数:
mt.randi

另外底下的常数除了birthday是原作者的生日(作者自重)以外其他都不要改了。后果貌似很严重……

  1. #============
  2. # rpg.blue
  3. # Mersenne Twister copycat version.
  4. # original: mt19937ar.c
  5. # author: viktor
  6. #============
  7. class MT19937
  8.   N = 624
  9.   M = 397
  10.   A = 0x9908b0df
  11.   MASK_S32 = 0x7fffffff
  12.   MASK_U32 = 0xffffffff
  13.   PRIMITIVE = 1812433253
  14.   BIRTHDAY = 19650218
  15.   MAGIC = [166_4525, 156_608_3941, 0x9d2c5680, 0xefc60000]
  16.   
  17.   attr_reader :seed
  18.   attr_reader :iv

  19.   def init_mt(s)
  20.     @mt[0] = s & MASK_U32
  21.     N.times{|i|@mt[i+1]=(PRIMITIVE * (@mt[i] ^ (@mt[i] >> 30))+i+1) & MASK_U32}
  22.     @life = N
  23.   end
  24.   
  25.   def init_array(iv)
  26.     @iv = iv   
  27.     i, j = 1, 0
  28.     [iv.length, N].max.times {
  29.       @mt[i] = (@mt[i] ^ (( @mt[i-1] ^ (@mt[i-1] >> 30 )) * MAGIC[0]))
  30.       @mt[i] =(@mt[i]+iv[j]+j) & MASK_U32
  31.       i+=1; j=(j+1) % iv.length
  32.       if i>=N
  33.         @mt[0] = @mt[N-1] # 折叠数组
  34.         i=1
  35.       end      
  36.     }
  37.     (N-1).times {
  38.       @mt[i] = (@mt[i] ^ (( @mt[i-1] ^ (@mt[i-1] >> 30 )) * MAGIC[1]))
  39.       @mt[i] =(@mt[i]-i) & MASK_U32
  40.       i+=1; if i>=N
  41.         @mt[0] = @mt[N-1]
  42.         i=1
  43.       end
  44.     }
  45.     @mt[0] = 0x80000000
  46.   end
  47.   
  48.   def randi
  49.     if @life >= N
  50.       # start a new round, update table mt
  51.       N.times {|k|
  52.         tmp = (@mt[k] & 0x80000000) | (@mt[(k+1)%N] & MASK_S32)
  53.         @mt[k] = @mt[(k+M)%N] ^ (tmp>>1) ^ (tmp[0]*A)
  54.       }
  55.       @life=0
  56.     end
  57.     ret = @mt[@life]
  58.     ret ^= (ret >> 11);
  59.     ret ^= (ret << 7) & MAGIC[2];
  60.     ret ^= (ret << 15) & MAGIC[3];
  61.     ret ^= (ret >> 18);
  62.     @life+=1
  63.     ret
  64.   end
  65.   
  66.   def initialize(seed=nil)
  67.     @mt=[]
  68.     srand(seed)
  69.   end
  70.   
  71.   def srand(seed=nil)
  72.     last_seed = @seed
  73.     seed = rand(1<<32) if seed==nil
  74.     @seed = seed
  75.     init_mt(@seed)
  76.     return last_seed
  77.   end
  78. end


  79. # test
  80. mt = MT19937.new(MT19937::BIRTHDAY)
  81. iv = [0x123, 0x234, 0x345, 0x456]
  82. mt.init_array iv
  83. out = []
  84. 1000.times {out << mt.randi}
  85. p out
复制代码

Lv2.观梦者

梦石
0
星屑
775
在线时间
924 小时
注册时间
2006-6-26
帖子
1529
2
发表于 2012-11-8 15:34:58 | 只看该作者
其实,我确实不懂脚本。
其实,我确实看不懂你说的是什么,但是,应该很赞。
总之,反正我看不懂。
我是不是可以签名了?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-5-2 13:35

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表