25

私は 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))

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

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

4

4 に答える 4

13

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、 http://osmf.sscc.ru/~smp/による元の Pascal コードの乗法乱数ジェネレーターです)

于 2013-11-24T17:20:39.877 に答える
10
math.randomseed(os.clock()*100000000000)
for i=1,3 do
    math.random(10000, 65000)
end

常に新しい乱数になります。シード値を変更すると、ランダム性が確保されます。os.time()これはエポック タイムであり、1 秒後に変化しos.clock()ますが、近いインスタンスでは同じ値にはならないため、従わないでください。

于 2015-09-02T12:30:32.833 に答える