Приближение к близкому приближению вероятности с использованием кода

Мне дали математический вопрос о вероятности. Это выглядит так:

Есть 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;
}

Теперь все эти коды выводят один и тот же текст:

Конечная вероятность = 1
Процесс завершен с кодом выхода 0

Кажется, что функция rand () выводила одно и то же значение на протяжении всех 100000 итераций цикла. Я не смог это исправить.

Я также попытался использовать функцию randomize () вместо функции srand (), но, похоже, она не работает и выдает странные ошибки, такие как:

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

Я думаю, что randomize () был прекращен в более поздних версиях C ++.

Я знаю, что я неправ на многих уровнях. Я был бы очень признателен, если бы вы терпеливо объяснили мне мои ошибки и сообщили мне некоторые возможные исправления.

1

Решение

Вы должны сбросить счет (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;
}

Типичный прогон будет выводить что-то вроде:

Ожидаемый: 0.632305
Рассчитано: 0,63125
0

Другие решения

Заполнить генератор псевдослучайных чисел можно только srand один раз в начале вашей программы. Когда вы заполняете его снова и снова, вы сбрасываете генератор псевдослучайных чисел в то же начальное состояние. time по умолчанию имеет гранулярность, измеряемую в секундах. Скорее всего, вы получаете все 1000 итераций — или большинство из них — в течение одной секунды.

0

Увидеть этот ответ на чужой вопрос для общего описания того, как работают генераторы псевдослучайных чисел.

Это означает, что вы должны быть создание одного экземпляра PRNG в вашей программе и сеять его один раз. Не выполняйте ни одну из этих задач внутри циклов или внутри функций, которые вызываются несколько раз, если вы действительно не знаете, что делаете, и не пытаетесь сделать что-то сложное, например, использовать стратегии индукции корреляции, такие как общие случайные числа или же антитетические вариации достигать «уменьшение дисперсии».

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector