使用代码到达概率的近似值

时间:2017-06-02 13:01:15

标签: c++ random probability discrete-mathematics

我接受了关于概率的数学问题。它是这样的:

  

有1000个彩票,每个彩票有1000张。你决定每次抽奖买1张票。你至少赢得一次彩票的几率是多少?

我能够在纸上以数学方式进行(到达1 - (999/1000)^ 1000),但是我想到了在我的计算机上进行随机实验的大量迭代的想法。所以,我输入了一些代码 - 确切地说是它的两个版本,并且都是故障。

代码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次迭代中输出相同的值。我无法解决这个问题。

我也尝试使用randomize()函数而不是srand()函数,但它似乎不起作用并且给出了奇怪的错误,如:

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

我认为randomize()已在更高版本的C ++中停止使用。

我知道我在很多层面都错了。如果你能耐心地向我解释我的错误并让我知道一些可能的更正,我将非常感激。

3 个答案:

答案 0 :(得分:0)

仅在程序开头按srand种子伪随机数生成器。当您一遍又一遍地播种时,将伪随机数生成器重置为相同的初始状态。默认情况下,time的粒度以秒为单位。可能性是你在一秒钟内完成所有1000次迭代 - 或大部分迭代。

答案 1 :(得分:0)

有关伪随机数生成器如何工作的一般描述,请参阅this answer to someone else's question

这意味着您应该 在您的计划中创建PRNG的一个实例 一次播种 。不要在循环内部执行这些任务,或者在多次调用的函数内部执行这些任务,除非您真正了解自己正在做什么并尝试执行复杂的操作,例如使用{{{{{{ 3}}或common random numbers来实现&#34; antithetic variates&#34;。

答案 2 :(得分:0)

您应该在外循环开始时重置计数(p1)。另外,请注意最终的整数除法p2/100000p2&lt; #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; } 100000将导致0。

查看代码的这个修改版本:

./eclipse -clean -debug -console -consolelog

一个典型的运行会输出类似:

Expected: 0.632305
Calculated: 0.63125