@monotonegative

Интересный вопрос от Я! Как решить проблему неправильных монет?

Не так давно, на вступительном испытании на стажировку мне попался следующий вопрос:
Условие
Есть набор из 100 нечестных монеток, у i-ой монеты вероятность выпадения орла равна 1/(2i+1), для (i = 1, 2, ... , 100). Результаты для каждой монеты являются независимыми. Вы бросили все монеты по одному разу, какова вероятность того, что мы получили нечетное количество орлов?

Формат вывода
Если ответ не является целым числом, запишите его в виде десятичной дроби, округлив ответ до 4 знаков после запятой или точки (формат (-)N,NNNN или (-)N.NNNN).


Мое решение (с пояснениями):
import numpy as np

"""     На первом этапе создается массив вероятностей выпадения орла 
    для 100 индивидуальных монет - orels.
"""
orels = []
for i in range (1,101, 1):
    probability = 1/(2*i + 1)
    orels.append(probability)
orels = np.asarray(orels)
"""     Также генерируется массив вероятностей выпадения решек - reshkas.
"""
reshkas = 1 - orels

print(reshkas)

"""     Самое вкусное! 
        Все решение основано на том, что наиболее вероятным НЕЧЕТНЫМ случаем 
    будет выборка с выпадением орла у первой монеты (шанс - 0.(3)) на 99 оставшихся решек.
    Следующий нечетный случай - 3 первых орла на 97 решек, затем 5 первых орлов на 95 решек и т.д.
        Почему я выбрал именно такую последовательность выпадения орлов, а не другую? 
    Да потому, что она наиболее вероятная)) - вероятность выпадения орлов с увеличением i, 
    можно сказать, стремиться к нулю.
        В конечном итоге нужно получит 50 выборок следующего вида:
    Odd_case1 = [О P P P P P...P[100]]
    Odd_case2 = [О O O P P P...P[100]]
    Odd_case3 = [О O O O O P...P[100]]
    ...
    Odd_case50 = [О O ...О[99] Р[100]]
    , где О - орел, Р - решка.

        Чтобы получить такие выборки я итерирую массив решек 'reshkas' с поиндексной 
    заменой i-ой решки на i-го орла из массива 'orels' c шагом 2. 
    В каждом цикле для каждой такой выборки мы  считаем общую вероятность 
    выпадения именно такой комбинации перемножив вероятности всех выпавших монет в выборке. 
        Полученные значения заносятся в новый массив 'oryol_probability', что является 
    массивом вероятностей выпадения i-го числа орлов, где i = 1, 3, 5 ... , 99.
"""

oryol_probability = []
for i in range (1, 100, 2):
    if reshkas[i] > 0:
        reshkas[:i] = orels[:i]
    # print(reshkas) - Unmute, если хотите отследить процесс замены.
    multyplied_coins = np.prod(reshkas)
    oryol_probability = np.append(oryol_probability, [multyplied_coins], axis = 0) 

print('Массив вероятностей выпадения i-го числа орлов:', oryol_probability) 

""" Ответ есть сумма полученных 50 общих вероятностей выборок, в которых наиболее вероятно выпало нечетное количество орлов. 
""" 

odd_orels_probability = np.sum(oryol_probability)
print('Ответ: ', '%.4f' % odd_orels_probability)

Мой ответ:
0.0460


Мое решение, ровно как и ответ, не претендуют на правильность. Вероятно все решается как-то иначе , мб даже без использования кода и достаточно лишь определенного багажа знаний теории вероятности. Буду рад услышать другие версии!
  • Вопрос задан
  • 2463 просмотра
Решения вопроса 2
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Предположим, что мы бросили n-1 монет и получили какое-то количество единиц (орлов). Бросаем следующую монету (n). Если выпадет ноль (решка), то количество единиц не изменится, и чётность останется той же. Если выпадет единица, то чётность изменится.
Poddn = Poddn-1*P0n + Pevenn-1*P1n
Pevenn = Pevenn-1*P0n + Poddn-1*P1n
Но, поскольку события Pevenn и Poddn образуют полный набор вариантов (либо чёт, либо нечет), то Pevenn + Poddn = 1.
Аналогично, P0n + P1n = 1.
Отсюда, Poddn = Poddn-1*(1-P1n) + (1-Poddn-1)*P1n
var Podd = 0;
var Peven = 1;
for (var i = 1; i <= 100; i++) {
  P1 = 1 / (2 * i + 1);
//  P0 = 1 - P1;
//  Po = Podd * P0 + Peven * P1;
//  Peven = Podd * P1 + Peven * P0;
//  Podd = Po;
// Всё, что выше, ужимается в
  Podd = Podd * (1 - P1) + (1 - Podd) * P1;
}
console.log(Podd);
// 0.49751243781094556
Ответ написан
longclaps
@longclaps
Орёлс, решкас... Стыдно-с лепить горбатого.
from fractions import Fraction


def foo(n):
    a, b = Fraction(1), Fraction(0)
    for i in range(n * 2, 0, -2):
        a, b = (a * i + b) / (i + 1), (a + b * i) / (i + 1),
    return b


print(foo(1))
print(foo(100))
Мое решение, рАвно как и ответ, претендуют на правильность, да-да-да )
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
lxsmkv
@lxsmkv
Test automation engineer
Вы в рассуждении говорите о "последовательности" выпадения. Тут нет никакой "последовательности". Монеты можно бросить все сразу или по очереди - разницы нет никакой.

Альтернативно можно решать другую задачу. У нас кубики с пронумерованными сторнами. Первый кубик имеет три стороны (ну представим себе такой), второй - пять, третий - 7, следующий - 2*i+1. Соответственно выбросить единицу на каждом кубике мы можем с вероятностью 1/2*i+1. Нас интересует вероятность того. что после броска всех кубиков количество единиц на них будет нечетным.
Вспомним элементарную задачу. Пусть у нас два шестигранных кубика. Как мы посчитаем вероятность того что мы получим две единицы? Количество благоприятствующих исходов к количеству возможных исходов. т.е. 1 исход из 11. Идем дальше, у нас два кубика. Какова вероятность того что мы бросим нечетное количество единиц? Это вероятность единицы на одном кубике помноженная на вероятнось "не-единицы" на другом. Т.е. 1/6 * 5/6.

Думаю такой подсказки будет достаточно.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы