Saltar al contenido

¿Python tiene una función que calcula coeficientes multinomiales?

Después de indagar en diversos repositorios y sitios webs al final hemos descubierto la solución que te enseñaremos a continuación.

Solución:

Para responder parcialmente a mi propia pregunta, aquí está mi implementación simple y bastante eficiente de la función multinomial:

def multinomial(lst):
    res, i = 1, 1
    for a in lst:
        for j in range(1,a+1):
            res *= i
            res //= j
            i += 1
    return res

Parece por los comentarios hasta ahora que no existe una implementación eficiente de la función en ninguna de las bibliotecas estándar.

Actualización (enero de 2020). Como ha señalado Don Hatch en los comentarios, esto se puede mejorar aún más buscando el argumento más grande (especialmente en el caso de que domine a todos los demás):

def multinomial(lst):
    res, i = 1, sum(lst)
    i0 = lst.index(max(lst))
    for a in lst[:i0] + lst[i0+1:]:
        for j in range(1,a+1):
            res *= i
            res //= j
            i -= 1
    return res

No, no hay una biblioteca o función multinomial incorporada en Python.

De todos modos, esta vez las matemáticas podrían ayudarte. De hecho, un método simple para calcular el multinomio

vigilar el rendimiento es reescribirlo utilizando la caracterización del coeficiente multinomial como producto de coeficientes binomiales:

donde por supuesto

Gracias a scipy.special.binom y la magia de la recursividad puedes resolver el problema así:

from scipy.special import binom

def multinomial(params):
    if len(params) == 1:
        return 1
    return binom(sum(params), params[-1]) * multinomial(params[:-1])

donde params = [n1, n2, ..., nk].

Nota: Dividir el multinomio como producto del binomio también es bueno para evitar el desbordamiento en general.

Tu escribiste sympy.ntheory.multinomial.multinomial_coefficients devuelve un diccionario relacionado con coeficientes multinomiales”, pero no queda claro a partir de ese comentario si sabe cómo extraer los coeficientes específicos de ese diccionario. Usando la notación del enlace de wikipedia, la función SymPy te da todo los coeficientes multinomiales para el dado metro y norte. Si solo desea un coeficiente específico, simplemente sáquelo del diccionario:

In [39]: from sympy import ntheory

In [40]: def sympy_multinomial(params):
    ...:     m = len(params)
    ...:     n = sum(params)
    ...:     return ntheory.multinomial_coefficients(m, n)[tuple(params)]
    ...: 

In [41]: sympy_multinomial([1, 2, 3])
Out[41]: 60

In [42]: sympy_multinomial([10, 20, 30])
Out[42]: 3553261127084984957001360

Busy Beaver dio una respuesta escrita en términos de scipy.special.binom. Un problema potencial con esa implementación es que binom(n, k) devuelve un valor de punto flotante. Si el coeficiente es lo suficientemente grande, no será exacto, por lo que probablemente no te ayude con un problema del Proyecto Euler. En vez de binom, puedes usar scipy.special.comb, con el argumento exact=True. Esta es la función de Busy Beaver, modificada para usar comb:

In [46]: from scipy.special import comb

In [47]: def scipy_multinomial(params):
    ...:     if len(params) == 1:
    ...:         return 1
    ...:     coeff = (comb(sum(params), params[-1], exact=True) *
    ...:              scipy_multinomial(params[:-1]))
    ...:     return coeff
    ...: 

In [48]: scipy_multinomial([1, 2, 3])
Out[48]: 60

In [49]: scipy_multinomial([10, 20, 30])
Out[49]: 3553261127084984957001360

Aquí puedes ver las reseñas y valoraciones de los usuarios

Si te ha sido de ayuda nuestro artículo, agradeceríamos que lo compartas con el resto entusiastas de la programación de este modo contrubuyes a difundir nuestra información.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *