Информация об изменениях

Сообщение Re: эрудит какашка от 04.12.2019 7:57

Изменено 04.12.2019 8:28 Erop

Re: эрудит какашка
Здравствуйте, SuhanovSergey, Вы писали:

SS>Какое самое простое объяснение решения?


если, вдруг, знает Питон, то что-то вроде:

def p_select_set_from( from_N, *n_from_m) :
    """
    вычисляет вероятность выбрать нужный набор букв в "эрудите"
    from_N -- оставшееся в мешке число фишек
    n_from_m -- набор пар (сколько_осталось_набрать_такой_буквы, сколько_осталось_в_мешке_такой_буквы)
    """
    if not n_from_m :
        return 1. #пустое множество всегда достанется из мешка за 0 действий ;)
    
    p = 0.0
    for i, nm in enumerate( n_from_m ):
        n, m = nm
        assert 1 <= n <= m 
        # условная вероятность выбрать такую фишку -- m/from_N
        # но её ещё нужно умножить на условную вероятность выбрать оставшееся множество
        if n == 1 :
            # такие фишки больше не нужны
            p += m/from_N * p_select_set_from(from_N-1, *n_from_m[:i], *n_from_m[i+1:])
        else :
            # такие фишки ещё нужны, но на 1 меньше и в мешке их останется на 1 меньше тоже
            p += m/from_N * p_select_set_from(from_N-1, *n_from_m[:i], (n-1, m-1), *n_from_m[i+1:])
    return p
    
p_select_set_from( 130, (3,9), (3,6), (1,1))


Печатает 1.5903430733516207e-08
Re: эрудит какашка
Здравствуйте, SuhanovSergey, Вы писали:

SS>Какое самое простое объяснение решения?


если, вдруг, знает Питон, то что-то вроде:

def p_select_set_from( from_N, *n_from_m) :
    """
    вычисляет вероятность выбрать нужный набор букв в "эрудите"
    from_N -- оставшееся в мешке число фишек
    n_from_m -- набор пар (сколько_осталось_набрать_такой_буквы, сколько_осталось_в_мешке_такой_буквы)
    """
    if not n_from_m :
        return 1. #пустое множество всегда достанется из мешка за 0 действий ;)
    
    p = 0.0
    for i, nm in enumerate( n_from_m ):
        n, m = nm
        assert 1 <= n <= m 
        # условная вероятность выбрать такую фишку -- m/from_N
        # но её ещё нужно умножить на условную вероятность выбрать оставшееся множество
        if n == 1 :
            # такие фишки больше не нужны
            p += m/from_N * p_select_set_from(from_N-1, *n_from_m[:i], *n_from_m[i+1:])
        else :
            # такие фишки ещё нужны, но на 1 меньше и в мешке их останется на 1 меньше тоже
            p += m/from_N * p_select_set_from(from_N-1, *n_from_m[:i], (n-1, m-1), *n_from_m[i+1:])
    return p
    
p_select_set_from( 130, (3,9), (3,6), (1,1))


Печатает 1.5903430733516207e-08

p. s.
А если вдруг знает-знает, то можно по-модному, по-молодёжному:
def f(from_N, *n_from_m) :
    return 1. if not n_from_m else sum( nm[1]* (
                f(from_N-1, *n_from_m[:i],                     *n_from_m[i+1:]) 
            if nm[0] == 1 else 
                f(from_N-1, *n_from_m[:i], (nm[0]-1, nm[1]-1), *n_from_m[i+1:])
                                               ) for i, nm in enumerate(n_from_m) ) / from_N