问题描述
我在Lua 4.0中没有访问random()的权限(不要问),所以我需要滚动自己的随机数生成器.或者更确切地说,我不得不推出另一种产品,因为我几年前实施的产品现在使我失败了. IE.我注意到重复的值很不好.
I don't have access to random() in Lua 4.0 (DON'T ASK), so I need to roll my own random number generator. Or rather I have to roll another one since the one I implemented several years ago is failing me now. I.e. I am noticing repeating values which is bad.
我可以使用Lua编写的任何建议或示例吗?仅供参考,这是我直到现在为止一直在用的那个:
Any suggestions or examples written in Lua that I can use? FYI here's the one I've been using up until now:
seedobja = 1103515245
seedobjc = 12345
seedobjm = 4294967295 --0x100000000
function srandom(seedobj, fVal1, fVal2)
seedobj[1] = mod(seedobj[1] * seedobja + seedobjc, seedobjm)
local temp_rand = seedobj[1] / (seedobjm - 1)
if (fVal2) then
return floor(fVal1 + 0.5 + temp_rand * (fVal2 - fVal1))
elseif (fVal1) then
return floor(temp_rand * fVal1) + 1
else
return temp_rand
end
end
以后的编辑已删除.
推荐答案
这是另一种尝试(始终为Lua 5.1代码),使用的是Knuth对减法生成器的C进行的适应(此时不是线性同余的).根据Knuth的说法,它应该与FP算术(甚至单精度)一起工作.
Here is another attempt (always Lua 5.1 code), using an adaptation from C of a subtractive generator by Knuth (not linear congruential then). According to Knuth it should work with FP arithmetic (even single precision).
local mod = math.fmod
local floor = math.floor
local abs = math.abs
local B = 4000000
-- rough adaptation of Knuth float generator
function srandom( seedobj, fVal1, fVal2 )
local ma = seedobj.ma
local seed = seedobj.seed
local mj, mk
if seed < 0 or not ma then
ma = {}
seedobj.ma = ma
mj = abs( 1618033 - abs( seed ) )
mj = mod( mj, B )
ma[55] = mj
mk = 1
for i = 1, 54 do
local ii = mod( 21 * i, 55 )
ma[ii] = mk
mk = mj - mk
if mk < 0 then mk = mk + B end
mj = ma[ii]
end
for k = 1, 4 do
for i = 1, 55 do
ma[i] = ma[i] - ma[ 1 + mod( i + 30, 55) ]
if ma[i] < 0 then ma[i] = ma[i] + B end
end
end
seedobj.inext = 0
seedobj.inextp = 31
seedobj.seed = 1
end -- if
local inext = seedobj.inext
local inextp = seedobj.inextp
inext = inext + 1
if inext == 56 then inext = 1 end
seedobj.inext = inext
inextp = inextp + 1
if inextp == 56 then inextp = 1 end
seedobj.inextp = inextp
mj = ma[ inext ] - ma[ inextp ]
if mj < 0 then mj = mj + B end
ma[ inext ] = mj
local temp_rand = mj / B
if fVal2 then
return floor( fVal1 + 0.5 + temp_rand * ( fVal2 - fVal1 ) )
elseif fVal1 then
return floor( temp_rand * fVal1 ) + 1
else
return temp_rand
end
end
-- test
-- Note: seedobj must be a table with a field named `seed`;
-- this field must be negative; after the first number has
-- been generated, the seedobj table will be populated with
-- additional state needed to generate numbers; changing its
-- `seed` field to a negative number will reinitialize the
-- generator and start a new pseudorandom sequence.
local seedobj = { seed = -232343 }
for i = 1, 100 do
print( srandom( seedobj, 100, 1000 ) )
end
这篇关于Lua 4.0随机数生成器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!