Generating uniform random numbers in Lua

前端 未结 4 1052
后悔当初
后悔当初 2020-12-01 16:07

I am working on programming a Markov chain in Lua, and one element of this requires me to uniformly generate random numbers. Here is a simplified example to illustrate my qu

相关标签:
4条回答
  • 2020-12-01 16:42

    Standard C random numbers generator used in Lua isn't guananteed to be good for simulation. The words "Markov chain" suggest that you may need a better one. Here's a generator widely used for Monte-Carlo calculations:

    local A1, A2 = 727595, 798405  -- 5^17=D20*A1+A2
    local D20, D40 = 1048576, 1099511627776  -- 2^20, 2^40
    local X1, X2 = 0, 1
    function rand()
        local U = X2*A2
        local V = (X1*A2 + X2*A1) % D20
        V = (V*D20 + U) % D40
        X1 = math.floor(V/D20)
        X2 = V - X1*D20
        return V/D40
    end
    

    It generates a number between 0 and 1, so r = math.floor(rand()*10) + 1 would go into your example. (That's multiplicative random number generator with period 2^38, multiplier 5^17 and modulo 2^40, original Pascal code by http://osmf.sscc.ru/~smp/)

    0 讨论(0)
  • 2020-12-01 16:59
    math.randomseed(os.clock()*100000000000)
    for i=1,3 do
        math.random(10000, 65000)
    end
    

    Always results in new random number. Changing seed value will ensure randomness, Dont follow os.time() cuz its epoch time and changes after one second but os.clock() dont have same value at any close instance. Cheers!

    0 讨论(0)
  • 2020-12-01 17:02

    There's the Luaossl library solution: (https://github.com/wahern/luaossl)

    local rand = require "openssl.rand"
    local randominteger
    if rand.ready() then -- rand has been properly seeded
        -- Returns a cryptographically strong uniform random integer in the interval [0, n−1].
        randominteger = rand.uniform(99) + 1 -- randomizes an integer from range 1 to 100
    end
    

    http://25thandclement.com/~william/projects/luaossl.pdf

    0 讨论(0)
  • 2020-12-01 17:06

    You need to run math.randomseed() once before using math.random(), like this:

    math.randomseed(os.time())
    

    From your comment that you saw the first number is still the same. This is caused by the implementation of random generator in some platforms.

    The solution is to pop some random numbers before using them for real:

    math.randomseed(os.time())
    math.random(); math.random(); math.random()
    

    Note that the standard C library random() is usually not so uniformly random, a better solution is to use a better random generator if your platform provides one.

    Reference: Lua Math Library

    0 讨论(0)
提交回复
热议问题