2016-02-09 4 views
6

私は何年もプログラムしていますが、私が今提示している問題はおそらく私が見ているうちで最も異常なものの1つです。ランダムに三つの可能なタイプで、一連のトークンを生成し、私のアプリのコードのブロックがあり乱数ジェネレータ(非決定的に作用する)

は、のは、A、BまたはC

だから、10個のトークンがあるかもしれないABCCAAABACをしましょう。コードのブロックの開始時に

は、乱数ジェネレータのシードはこれのように初期化される:シード値が一定とき

math.randomseed(seed) 
math.random() 

さて、当然、私は常に、トークンの同じシーケンスを取得し、ので、ランダム生成コードは決定論的な方法で実行される。まあ、ほぼです。

実際には、まれに、青から同じ種子を与えられた異なるランダム配列が得られます。その後、私はそれを知る前に正常に戻ります。あなたはおそらく考えている - ああ、副作用、これはおそらく、トークンのランダムなシーケンスを生成するコードのブロックが何回(例えば)random()を呼び出すかを変更する変数を利用する状態関連の問題です。しかし、私はすべての明白な副作用のために制御していると確信しています。外部の状態にアクセスするコードブロックにはわずかな場所しかなく、それらはすべて一定のままです。

プロットがさらに濃くなりました。この問題は、私が構築してきたアプリのAndroidデプロイメントで私には明らかでした。確かに、これはまれなバグであり、確実に繰り返すことはできません。したがって、iOSデプロイメントにも存在する可能性があります。しかし、私はまだそれを他のプラットフォームで見てきました。私は、アプリを開発するためにCorona SDKを通してluaスクリプトを使用していることにも言及しています。

私はこの問題に多くの思考を与えている、といくつかの可能性に絞られている:私は

  • を知らないんだ同じ乱数ジェネレータを使用して、別のスレッド、(と

    1. インタラクションLUAでこのさえ可能ですか?)ヒープ破損のいくつかの並べ替えは、奇妙な副作用につながっている
    2. 私はめちゃめちゃてきたと私はデバッグの多くの時間全体で見逃している外部の状態にいくつか気明白な参照があります

    この中で最も厄介な点は、バグの非再現性です。ほとんどの場合、コードブロックは繰り返しの種を与えられて完全に確定的に動作します。それで、非決定論のフェーズがあるかのようであり、それは次に何らかの未知の時間の後に再び散逸する。私はここで専門家の脳を選ぶのが大好きです。

    ここで何が起こっている可能性がありますか?また、Androidのデプロイメントでしか見ていないので、この特定の問題に関してプラットフォーム固有のものがある可能性はありますか?

    参考までに、完全なコードブロックを示します。実際には、2つのランダムなプロパティ(3つの色の1つと3つの図形の1つ)を持つトークンを生成していますが、それは問題の本質の点ではあまり意味がありません。

    math.randomseed(currentRandomSeed) 
    math.random() 
    
    local tokenListPlan = {} 
    
    -- randomly assign weighting distribution 
    local thresh1, thresh2 
    while (true) do 
        local s0 = math.random(1, 99) 
        local s1 = math.random(1, 99) 
        local c0 = s0 
        local c1 = s1 - c0 
        local c2 = 100 - c1 - c0 
        if (c0 >= eng.DEVIATION_THRESHOLD and c1 >= eng.DEVIATION_THRESHOLD and c2 >= eng.DEVIATION_THRESHOLD) then 
         thresh1 = c0 
         thresh2 = c0 + c1 
         break 
        end 
    end 
    
    -- generate tokens (deterministic based on seed) 
    for i = 1, sortedCountTarget do 
        local token 
        local c = 1 
    
        local rnd = math.random(1, 100) 
        if (rnd < thresh1) then -- skewed dist 
         c = 1 
        elseif (rnd < thresh2) then 
         c = 2 
        else 
         c = 3 
        end 
    
        if (paramGameMode == eng.GAME_MODE_COLOR) then 
         local rnd46 = math.random(4, 6) 
         token = {color = c, shape = rnd46} 
        elseif (paramGameMode == eng.GAME_MODE_SHAPE) then 
         local rnd13 = math.random(1, 3) 
         token = {color = rnd13, shape = c + 3} 
        else 
         local rnd13 = math.random(1, 3) 
         local rnd46 = math.random(4, 6) 
         token = {color = rnd13, shape = rnd46} 
        end 
    
        tokenListPlan[#tokenListPlan + 1] = token 
    end 
    
  • +0

    ここでは、正確にランダムシードを設定していますか?アンドロイドでは、何らかの理由でランダムセッティングラインが2回以上実行されることがあります。 – muratgu

    +0

    コードのブロックの直前(その間に何もない)に、ここであまりあいまいでないように投稿を編集します。残念ながら、私はそれが何度も実行される可能性はありません。特に散発的ではありません。 –

    +2

    math.randomは、このコードが実行されている間に予想される量以上のものを起動する場合がありますか?クロージャを使用して呼び出された量を数える関数にラップしてみてください。異なる結果が出たときに変更されているかどうかを確認してください。 – warspyking

    答えて

    1

    https://docs.coronalabs.com/api/library/math/random.html状態:

    この関数はANSI C.無保証によって提供される単純な擬似乱数生成関数ランドへのインタフェースは、その統計的特性のために与えることができるです。

    これは、他のプログラムが同じ機能を使用しているのかどうか疑問です。 それはそれらの葛藤につながる可能性がありますが、それは時にはたまにしか起こらない理由を多少説明します。

    関連する問題