Источник: ошибка в 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))
и т.д., который чувствует, что он победит точку работы в лог-пространстве`?
Кто-нибудь лучше понимает, что я должен делать?