2017-06-02 4 views
1

確率についての数学的質問が与えられました。これは次のようになります。コードを使用して確率を近似して到着すると、

1000件の宝くじがあり、それぞれ1000件のチケットがあります。宝くじごとに1枚のチケットを購入することにします。あなたは少なくともで勝つ確率はどれくらいですか宝くじ?

私は紙の上に数学的にそれを行うことができました(1に到着しました - 1000年^)1000分の999()、しかし、私のコンピュータ上のランダム実験の大規模な反復を行うという考えは私に起こりました。だから、私はいくつかのコードを入力しました - 正確には2つのバージョン、両方とも誤動作しました。

コード1:

#include<iostream> 
#include <stdlib.h> 

using namespace std; 

int main() { 
    int p2 = 0; 
    int p1 = 0; 
    srand(time(NULL)); 
    for (int i = 0; i<100000; i++){ 
     for(int j = 0; j<1000; j++){ 
      int s = 0; 
      int x = rand()%1000; 
      int y = rand()%1000; 
      if(x == y) 
       s = 1; 
      p1 += s; 
     } 
     if(p1>0) 
      p2++; 
    } 
    cout<<"The final probability is = "<< (p2/100000); 
    return 0; 
} 

コード2:

#include<iostream> 

#include <stdlib.h> 

using namespace std; 

int main() { 
    int p2 = 0; 
    int p1 = 0; 
    for (int i = 0; i<100000; i++){ 
     for(int j = 0; j<1000; j++){ 
      int s = 0; 
      srand(time(NULL)); 
      int x = rand()%1000; 
      srand(time(NULL)); 
      int y = rand()%1000; 
      if(x == y) 
       s = 1; 
      p1 += s; 
     } 
     if(p1>0) 
      p2++; 
    } 
    cout<<"The final probability is = "<< (p2/100000); 
    return 0; 
} 

コード3(いくつかの先進的なテキストを参照のことが、私はそれのほとんどを理解していない):

#include<iostream> 

#include <random> 

using namespace std; 

int main() { 
    int p2 = 0; 
    int p1 = 0; 
    random_device rd; 
    mt19937 gen(rd()); 
    for (int i = 0; i<100000; i++){ 
     for(int j = 0; j<1000; j++){ 
      uniform_int_distribution<> dis(1, 1000); 
      int s = 0; 
      int x = dis(gen); 
      int y = dis(gen); 
      if(x == y) 
       s = 1; 
      p1 += s; 
     } 
     if(p1>0) 
      p2++; 
    } 
    cout<<"The final probability is = "<< (p2/100000); 
    return 0; 
} 

これらのコードはすべて同じテキストを出力します:

The final probability is = 1 
Process finished with exit code 0 

rand()関数は、ループの100000回の反復全体で同じ値を出力しているようです。私はこれを解決することができませんでした。

私はまた、代わりにsrand()関数のランダム化()関数を使用してみましたが、動作するようには思えないなどの奇妙なエラーを与える:私は(そのランダマイズを考える

error: ‘randomize’ was not declared in this scope 
randomize(); 
     ^

)が中止されていますC++のそれ以降のバージョンでは、

私は多くのレベルで間違っていることを知っています。あなたが私の間違いを忍耐強く説明し、いくつかの可能な修正を私に教えてもらえれば、本当にありがたく思います。

答えて

0

外側ループの先頭にカウント(p1)をリセットする必要があります。また、最終整数除算p2/100000を認識して、p2 < 100000の任意の値は、あなたのコードのこの修正版では0

ルックにつながる:

#include <iostream> 
#include <random> 

int main() 
{ 
    const int number_of_tests = 100000; 
    const int lotteries = 1000; 
    const int tickets_per_lottery = 1000; 

    std::random_device rd; 
    std::mt19937 gen(rd()); 
    std::uniform_int_distribution<> lottery(1, tickets_per_lottery); 

    int winning_cases = 0; 
    for (int i = 0; i < number_of_tests; ++i) 
    { 
     int wins = 0;       // <- reset when each test start 
     for(int j = 0; j < lotteries; ++j) 
     { 
      int my_ticket = lottery(gen); 
      int winner = lottery(gen); 
      if(my_ticket == winner) 
       ++wins; 
     } 
     if (wins > 0) 
      ++winning_cases; 
    } 
    // use the correct type to perform these calculations 
    double expected = 1.0 - std::pow((lotteries - 1.0)/lotteries, lotteries); 
    double probability = static_cast<double>(winning_cases)/number_of_tests; 

    std::cout << "Expected: " << expected 
       << "\nCalculated: " << probability << '\n'; 

    return 0; 
} 

tipicalの実行を希望出力何かlike:

 
Expected: 0.632305 
Calculated: 0.63125 
0

プログラムの先頭に一度だけ擬似乱数生成器をsrandでシードします。それを何回も何度もシードすると、擬似乱数ジェネレータが同じ初期状態にリセットされます。 timeはデフォルトで秒単位で測定された粒度を持ちます。 1秒間に1000回以上の反復が行われています。

+0

私は最初のコードで試したことがあります。同じループで新しい乱数を生成できないという問題をどのように回避するには? xとyについて –

0

擬似乱数発生器の一般的な説明については、this answer to someone else's questionを参照してください。

これは、あなたがはそれを1時間播種つのインスタンスあなたのプログラムでPRNGのとを作成しなければならないことを意味しています。あなたが何をしているのかを実際に知っておらず、common random numbersantithetic variatesなどの相関誘導戦略を使用するなど、洗練された何かをしようとしていない限り、ループ内でこれらのタスクを実行したり、 variance reduction "。

関連する問題