web-dev-qa-db-ja.com

Luaで均一な乱数を生成する

私はLuaでマルコフチェーンのプログラミングに取り組んでおり、その1つの要素として、乱数を均一に生成する必要があります。これが私の質問を説明する簡単な例です:

_example = function(x)
    local r = math.random(1,10)
    print(r)
    return x[r]
end

exampleArray = {"a","b","c","d","e","f","g","h","i","j"}

print(example(exampleArray))
_

私の問題は、このプログラムを複数回再実行すると(マッシュ F5)まったく同じ乱数が生成され、関数の例ではまったく同じ配列要素が選択されます。ただし、最後の印刷行を何度も繰り返すことにより、単一のプログラム内にサンプル関数への多くの呼び出しを含めると、適切なランダムな結果が得られます。

適切なマルコフ擬似ランダムテキストジェネレーターが同じプログラムを同じ入力で複数回実行でき、毎回異なる擬似ランダムテキストを出力できるはずなので、これは私の意図ではありません。 math.randomseed(os.time())を使用してシードをリセットしようとしましたが、これにより乱数の分布が均一でなくなります。私の目標は、上記のプログラムを再実行して、毎回ランダムに選択された数を受け取ることができるようにすることです。

15
Starfish_Prime

次のように、math.randomseed()を使用する前に、math.random()onceを実行する必要があります。

_math.randomseed(os.time())
_

あなたが最初の数字を見たというあなたのコメントから、まだ同じです。これは、一部のプラットフォームでのランダムジェネレーターの実装が原因です。

解決策は、実際に使用する前にいくつかの乱数をポップすることです:

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

標準Cライブラリrandom()は通常、均一にランダムではないことに注意してください。プラットフォームが提供している場合は、より良いランダムジェネレーターを使用することをお勧めします。

リファレンス: Lua Math Library

10
Yu Hao

Luaで使用されている標準C乱数ジェネレーターは、シミュレーションに適しているとは保証されていません。 「マルコフ連鎖」という言葉は、もっと良いものが必要かもしれないことを示唆しています。以下は、モンテカルロ計算に広く使用されているジェネレータです。

_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
_

0と1の間の数を生成するので、r = math.floor(Rand()*10) + 1はあなたの例に入ります。 (これは、周期2 ^ 38、乗数5 ^ 17、モジュロ2 ^ 40、元のPascalコード http://osmf.sscc.ru/~smp/ を使用した乗算乱数ジェネレータです)

11
GrayFace
_math.randomseed(os.clock()*100000000000)
for i=1,3 do
    math.random(10000, 65000)
end
_

常に新しい乱数になります。シード値を変更するとランダム性が確保されます。エポック時間をos.time()に追跡しないでください。1秒後に変更されますが、os.clock()はどの近いインスタンスでも同じ値を持ちません。乾杯!

5
daemonsl