2017-12-22 1 views
3

ユーザーが3つのドアの1つを選択するよう求められたときに、ドアを切り替えるように求められているMonty Hallの問題をモデル化しようとしています。私は選択肢のランダムなバリエーションを探していますが、これは50%の変化率と50%の変化率の範囲にあるはずです。Rubyの乱数ジェネレータがイニシャライザから呼び出されたときに歪んでいます

class Scenario 
    def initialize 
    # switched? 
    end 

    def switched? 
    @sw ||= [true, false].sample 
    end 
end 

results = { switched: [], stayed: [] } 

1000.times do 
    s = Scenario.new 

    if s.switched? 
    results[:switched].push(s) 
    else 
    results[:stayed].push(s) 
    end 
end 

puts results[:switched].count 
puts results[:stayed].count 

私は結果のハッシュを検査する場合、この例では、配列の数が予想通りおよそ500/500になる傾向があります。

ただし、初期化メソッドでswitched?のコメントを外すと、結果は約750/250に分割される傾向があります。結果はまだランダムに見えます(例:738〜262)が、この問題の不正な解決策になるように常に歪んでいます。

私はまた、rand(2).zero?のような他のメカニズムを使用してデータを生成しようとしましたが、同じ問題が発生します。

なぜこの方法で初期化された関数を呼び出すと、これまでのランダムなバリエーションが発生するのでしょうか?

+0

どちらの場合でも 'initialize'メソッドを表示できますか?初期化メソッドで '|| ='を使用していますか? –

+0

[mcve]を入力してください。あなたはその振る舞いについて素晴らしい説明をしてきましたが、それをどのように生成したのかに関する不完全なコードサンプルがありました。したがって**あなたの問題を**再現する方法はわかりません。 –

+4

しかし、推測では、あなたは 'switched?' ** 2回**と呼んでいるのではなく、変数が 'true'の場合にのみメモに記録されますか?ランダムに 'false'を選択した場合、' || = 'は再評価されます。したがって、「真」が時間の75%に選ばれる。 –

答えて

5

ルビーでは、nilfalse以外のすべての値は「真実」とみなされます。

あなたがfoo ||= barを呼び出すと、barfooは「falsey」である場合にのみ評価されます - nilまたはfalseに、すなわち等しいです。 (!か、未定義の場合)

をあなたのコードでは、次があります。

def switched? 
    @sw ||= [true, false].sample 
end 

ので、@sw変数は、メソッド呼び出しのみ[true, false].sample場合リターンtrueの結果をmemoizeます!

これは、switched?を複数回呼び出すと、@sw変数に "multiple attempts"という変数をランダムに指定してtrueをランダムに選択するということです。

switched?に電話すると、trueの確率は50%です。それを2度呼び、75%の可能性があります(あなたが観察したように)。それを3回呼び出すと、87.5%の可能性があります。等々。

潜在的にfalseの値をメモするには、構文をもう少し明示する必要があります。

def switched? 
    return @sw if defined?(@sw) 
    @sw = [true, false].sample 
end 

switched?に複数回安全に電話をかけることができます。 falseであっても最初の結果を覚えており、再計算しません。

関連する問題