Это классическая вероятностная головоломка, и, насколько мне известно, вы не можете сделать это всего лишь двумя вызовами функции. Однако вы можете сделать это с небольшим ожидаемым количеством вызовов функции.
Наблюдение состоит в том, что если у вас есть предвзятая монета, которая выпадает в голову с вероятностью p, и если вы дважды подбрасываете монету, то:
- Вероятность того, что он поднимется головой дважды, равна p 2
- Вероятность того, что он пойдет первым, а вторым - p (1-p)
- Вероятность того, что он придет первым, а затем головой, составляет (1-p) p
- Вероятность того, что он выползет дважды, равна (1-р) 2
Теперь предположим, что вы несколько раз подбрасываете две монеты, пока они не примут разные значения. Если это произойдет, какова вероятность, что первая монета выпала в голову? Ну, если мы применим закон Байеса, мы получим, что
P (первая монета - головы | обе монеты разные) = P (обе монеты разные | первая монета - головы) P (первая монета - головы) / P (обе монеты разные)
Вероятность того, что первая монета является головкой, равна p, поскольку любой бросок монеты выпадает из головы с вероятностью p. Вероятность того, что обе монеты различны, учитывая, что первая монета является головкой, - это вероятность того, что вторая монета выпала хвостом, (1 - p). Наконец, вероятность того, что обе монеты различны, составляет 2p (1-p), поскольку, если вы посмотрите на таблицу вероятностей выше, это может произойти двумя способами, каждый из которых имеет вероятность p (1-p). Упрощая, мы получаем, что
P (первая монета - голова | обе монеты разные) = p (1-p) / (2p (1-p)) = 1 / 2.
Но есть ли вероятность, что первая монета выпадет в хвост, если монеты разные? Ну, это то же самое, что вероятность того, что первая монета не выпала в голову, когда обе монеты разные, что составляет 1 - 1/2 = 1 / 2.
Другими словами, если вы продолжаете подбрасывать две монеты до тех пор, пока они не примут разные значения, а затем возьмите значение первой подброшенной монеты, вы в конечном итоге сделаете честную монету из смещенной монеты!
В Си это может выглядеть так:
bool FairCoinFromBiasedCoin() {
bool coin1, coin2;
do {
coin1 = function_A();
coin2 = function_A();
} while (coin1 == coin2);
return coin1;
}
Это может показаться ужасно неэффективным, но на самом деле все не так плохо. Вероятность того, что он завершится на каждой итерации, равна 2p (1 - p). В ожидании, это означает, что нам нужно 1 / (2p (1-p)) итераций, прежде чем этот цикл завершится. Для p = 40% это 1 / (2 x 0,4 x 0,6) = 1 / 0,48 ~ = 2,083 итерации. Каждая итерация подбрасывает две монеты, поэтому нам нужно, как и ожидалось, около 4,16 подбрасывания монет, чтобы получить справедливый бросок.
Надеюсь, это поможет!