Можете ли вы упростить суммирование биномиальных произведений - PullRequest
0 голосов
/ 08 января 2019

Есть ли способ упростить следующий термин:

сумма (binom (m, i) * binom (n, i) * factorial (i), i = 1..min (n, m))

где бином - биноминальный коэффициент.

Спасибо!

1 Ответ

0 голосов
/ 08 января 2019

Так как это - stackoverflow, а не math.stackexchange, разумно предположить, что вы фактически планируете реализовать программу для вычисления этой суммы. Имея это в виду, я сделаю несколько «упрощений», которые вы обычно не сделали бы в чисто математических / гипотетических условиях.

Во-первых, знайте, что

binom(n, i) => factorial(n) / (factorial(i) * factorial(n - i))

Включив это в ваше уравнение, мы можем отменить два factorial(i) условия.

factorial(n) * factorial(m) / ((factorial(i) * factorial(n - i) * factorial(m - i))

Теперь, если мы создадим функцию product(a, b), которая принимает произведение всех чисел [a, b] включительно, мы можем разделить эти факториалы на диапазоны, которые исключают. Чтобы сделать следующий фрагмент более кратким, я сокращаю факториал как fac, а продукт как prod.

fac(n)*fac(m) / (fac(i) * fac(n-i) * fac(m-i))
=> prod(m+1, n) * fac(m)**2 / (fac(i) * fac(n-i) * fac(m-i))
=> prod(m+1, n) * fac(m)**2 / (fac(i) * prod(m-i+1,n-i) * fac(m-i)**2)
=> prod(m+1, n) * prod(m-i+1,m)**2 / (fac(i) * prod(m-i+1,n-i))
=> prod(m+1, n) * prod(m-i+1,m) / (fac(i) * prod(m+1,n-i))
=> prod(n-i+1, n) * prod(m-i+1,m) / fac(i)

Итак, в конце мы имеем

product(n-i+1, n) * product(m-i+1,m) / factorial(i)

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

Первый вариант - начать умножать значения в каждом product() и попытаться выделить меньшие коэффициенты из factorial(). Однако это может занять много времени, так как вы потратите гораздо больше времени на проверку делимости, чем на фактическое уменьшение числа.

Другой вариант - создать три набора, представляющих числа, которые нужно умножить при каждом вызове функции. Затем возьмите пересечение одного из product наборов с набором factorial и вычтите эти элементы из каждого из исходных наборов. Затем повторите этот процесс с другим набором product и новым набором factorial. Затем умножьте значения в каждом наборе, как и раньше.

Еще более разумный вариант - получить простую факторизацию каждого числа, умноженного на product() и factorial() (возможно, с помощью таблицы поиска), а затем просто сложить счетчики каждого фактора в product() и вычесть factorial(). Затем вы можете просто умножить на степени каждого простого множителя, которые сами могут быть вычислены быстрее путем возведения в степень путем возведения в квадрат (или даже справочных таблиц для меньших степеней и факторов).

...