Работа с небольшими вероятностями через журналы

Источник: ошибка в Google Code. https://code.google.com/codejam/contest/10224486/dashboard#s=a&a=1

Мы попросили рассчитать Prob (K успехов из N испытаний), где каждое из N испытаний имеет известную вероятность успеха p_n.

Некоторые анализы и мысли по проблеме задаются после пробки кода.

Они отмечают, что оценка всех возможных результатов ваших испытаний N приведет к экспоненциальному времени в N, поэтому вместо этого они обеспечивают хорошее решение стиля "динамического программирования", которое O (N ^ 2).

Пусть P (p # q) = Prob (p Успехи после первых q испытаний) Тогда заметим, что:

Prob(p#q) = Prob(qth trial succeeds)*P(p-1#q-1) + Prob(qth trial fails)*P(p#q-1)

Теперь мы можем построить таблицу P (i # j), где я <= j, для я = 1... N

Что все прекрасное - я следую всему этому и могу его реализовать.


Затем, как последний комментарий, они говорят:

In practice, in problems like this, one should store the logarithms of
probabilities instead of the actual values, which can become small
enough for floating-point precision errors to matter.

Я думаю, что в целом понимаю, что они пытаются сделать, но я не могу понять, как использовать это предложение.

Взяв вышеприведенное уравнение и подставив в него некоторые буквенные переменные:

P = A*B + C*D

Если мы хотим работать в Log Space, мы имеем:

Log(P) = Log(A*B + C*D),

где мы рекурсивно предварительно вычислено Log(B) и Log(D), а A и B известны, легко обрабатываемые десятичные числа.

Но я не вижу никакого способа вычислить Log(P), не делая просто e^(Log(B)) и т.д., который чувствует, что он победит точку работы в лог-пространстве`?

Кто-нибудь лучше понимает, что я должен делать?

Ответ 1

Начиная с начального отношения:

P = A⋅B + C⋅D

Из-за его симметрии мы можем предположить, что B больше, чем D, без потери общности. Полезна следующая обработка:

log (P) = log (A⋅B + C⋅D) = log (A⋅e log(B) + C⋅e log(D)) = log (e log(B) ⋅ (A + C⋅e log(D) - log(B))

log (P) = log (B) + log (A + C⋅e log(D) - log(B)).

Это полезно, потому что в этом случае log (B) и log (D) являются отрицательными числами (логарифмы некоторых вероятностей). Предполагалось, что B больше, чем D, поэтому его лог ближе к нулю. Следовательно, log (D) - log (B) по-прежнему отрицательно, но не так отрицательно, как log (D).

Так что теперь вместо того, чтобы выполнять возведение в степень log (B) и log (D) по отдельности, нам нужно только возвести возведение в степень log (D) - log (B), который является слегка отрицательным числом. Таким образом, приведенная выше обработка приводит к лучшему числовому поведению, чем использование логарифмов и тривиальным способом возведения в степень, или, что эквивалентно, чем не использование логарифмов вообще.