В интервью мне была предложена следующая проблема: сначала решить проблему с использованием ручки/бумаги, а затем с помощью программы для проверки результата.
Вопрос заключается в следующем:
Есть три человека A, B и C. Каждый человек способен поразить цель с вероятностью 6/7, 4/5 и 3/4 соответственно. Какова вероятность того, что если бы каждый из них выстрелил, то ровно двое из них попали в цель?
Ответ:
P(...) = P(A)*P(B)*(1-P(C)) +
P(B)*P(C)*(1-P(A)) +
P(C)*P(A)*(1-P(B))
= 27.0/70.0
= 38.57142857142857142857142857142857142857....%
Ниже мое решение проблемы:
#include <cstdio>
#include <cctype>
#include <ctime>
#include <random>
int main()
{
std::mt19937 engine(time(0));
engine.discard(10000000);
std::uniform_real_distribution<double> uniform_real(0.0,1.0);
double prA = (6.0 / 7.0);
double prB = (4.0 / 5.0);
double prC = (3.0 / 4.0);
std::size_t trails = 4000000000;
std::size_t total_success = 0;
for (std::size_t i = 0; i < trails; ++i)
{
int current_success = 0;
if (uniform_real(engine) < prA) ++current_success;
if (uniform_real(engine) < prB) ++current_success;
if (uniform_real(engine) < prC) ++current_success;
if (current_success == 2)
++total_success;
double prob = (total_success * 1.0) / (i+1);
if ((i % 1000000) == 0)
{
printf("%05d Pr(...) = %12.10f error:%15.13f\n",
i,
prob,
std::abs((27.0/70.0) - prob));
}
}
return 0;
}
Проблема заключается в следующем, независимо от того, насколько велика серия проб, которые я запускаю, вероятность плоских линий около примерно 0,8585002101. Что-то не так в коде?
Интервьюер сказал, что тривиально получить результат, чтобы сблизиться до 9 десятичных знаков в пределах 1 миллиона проб, независимо от семени.
Любые идеи о том, где ошибка в моем коде?
ОБНОВЛЕНИЕ 1: Я пробовал приведенный выше код со следующими генераторами, все они кажутся платау примерно в то же время примерно пробным 10 ^ 9.
- std:: mt19937_64
- std:: ranlux48_base
- станд:: minstd_rand0
ОБНОВЛЕНИЕ 2: Размышляя о проблеме, я пошел по следующему треку. Соотношение 27/70 составило 27 и 70, которые оба взаимно просты и где коэффициенты 70 при 4x10 ^ 9 составляют примерно 57x10 ^ 6 или около 1,4% от всех чисел. Следовательно, вероятность получения "точного" соотношения 27/70 из двух чисел, выбранных случайным образом между [0,4x10 ^ 9], составляет примерно 1,4% (так как в пределах 4 × 10 9 9 больше факторов 27). Таким образом, получение точное соотношение очень низкое, и это число будет постоянным независимо от количества испытаний.
Теперь, если говорить о толстых границах - то есть: числа в диапазоне коэффициентов 70 +/5, что увеличивает вероятность выбора пары чисел случайным образом в диапазоне [0,4x10 ^ 9], что будет давать отношение в пределах указанной/относительной толерантности примерно до 14%, но с этой методикой лучшее, что мы можем получить, будет в среднем примерно 5 десятичных знаков точным по сравнению с точным значением. Правильно ли этот способ рассуждения?