【问题标题】:Python function to solve binomial functionPython函数求解二项式函数
【发布时间】:2016-05-10 19:54:18
【问题描述】:

我需要一个可以解决以下问题的函数:对于二项式函数 nCr=k,给定 r 和 k 找到 n。在数学中 nCr=n!/r!(n-r)!我尝试了以下但它没有解决它。例如 8C6=28,对于我的函数,输入是 6 和 28,我想找到 8。这可能没有确切的整数,所以我想找到一个 x>=n。

"""
I am approaching it this way, i.e. find the solution of a polynomial function  iteratively, hope there is a better way"""
"""I am approaching it this way, i.e. find the solution of a polynomial function iteratively, hope there is a better way"""
def find_n(r,k):
    #solve_for_n_in(n*(n-1)...(n-r)=math.factorial(r)*k
    #in the above example solve_for_n(n*(n-1)(n-2)(n-3)(n-4)(n-5)=720*28)

    sum=math.factorial(r)*k
    n=r
    p=1
    while p<sum: 
        p=1
        for i in range(0,r+2):
            p*=(n-i+1)
        n+=1
    return n

谢谢。

【问题讨论】:

  • 只要正确计算......你的想法显然是存储 n/(n-r)!在“sum”中并将其与 r!k 进行比较,但“sum”计算错误。在第一次迭代中,总和等于 n,然后是 (n-1)^2,然后是 (n-2)^2*(n-1),依此类推...
  • 嗨@jomuel 我修改了它,但有时它没有得到结果。

标签: python numpy combinatorics itertools discrete-mathematics


【解决方案1】:

我发现你的代码有一个错误。

sum=n

您将 sum 设置为 n 那么,

while sum<factorial(r)*k:
    sum*=n

你再次将 sum 乘以 n。所以现在总和 = n ** 2。 这样会更好:

  while sum<factorial(r)*k:
    n+=1
    sum*=n

【讨论】:

    【解决方案2】:

    这只是一个关于如何解决这个问题的想法,同时保持高度的可读性。

    nCr = n! / {{r!}{n-r}!} = n(n-1)...(n-r+1) / {r!} 右边是一些值k

    n = 2*(r+1) 开头。

    nCr &lt; RHS => n 太小 => 增加 n

    nCr &gt; RHS => n 太大 => 减小 n

    nCr == RHS => 找到 n

    ... ... 继续这样做,直到找到n 或出现问题。

    import math
    
    def find_n(r,k):
    
        if k==1:
            return r         # RHS is 1 when n and r are the same
    
        RHS = math.factorial(r) * k
    
        possible_n = 2 * r;
        possible_numerator = math.factorial(possible_n)
        possible_denom = math.factorial(possible_n - r)
    
        while True:
            # current n is too small 
            if ( possible_numerator // possible_denom ) < RHS:
                # try possible_n + 1
                possible_n = possible_n + 1
                possible_numerator = math.factorial(possible_n)
                possible_denom = math.factorial(possible_n - r)
    
            elif ( possible_numerator // possible_denom ) > RHS:
                # try possible_n - 1
                possible_n = possible_n - 1
                possible_numerator = math.factorial(possible_n)
                possible_denom = math.factorial(possible_n - r)
    
            elif ( possible_n == r):
                print ("***n smaller than r***");
                sys.exit(0);
    
            elif ( possible_numerator // possible_denom ) == RHS:
                return possible_n
    
    
    
    
    
    print( find_n(6, 28) )      # should print 8
    
    print( find_n(6, 462) )     # should print 11 
    
    print( find_n(6, 3003) )        # should print 14
    
    print( find_n(5, 3003) )        # should print 15
    

    【讨论】:

    • 如果关心性能,开始在地图或数组或其他东西中缓存阶乘的值。
    • 第一个灵感来自于你提到x&gt;=n。现在,从r+1 开始搜索并没有多大意义,因为如果您开始在地图中缓存值,那将无济于事。如果r 很小,2*r+1 并不重要,但是随着r 的大小增长,阶乘会变得昂贵,并且缓存将使您在基本上 O(1) 中获得阶乘。考虑到可读性,这似乎是最简单的方法。
    • 如果您从 r+1 开始缓存阶乘值并继续,您将很快耗尽堆空间(在 Java 中测试)。所以,它是不​​可扩展的。
    【解决方案3】:

    我使用了一个计算二项式系数的函数来实现特征nCr

    def binomial(n,k):
        return 1 if k==0 else (0 if n==0 else binomial(n-1, k) + binomial(n-1, k-1))
    
    def nCr(r,c):
        n=0
        b=binomial(n,r)
        while b<c:
            n=n+1
            b=binomial(n,r)
            if b==c:
                return n
    
        return None
    

    nCr(6,28)

    8

    【讨论】:

      猜你喜欢
      • 2020-09-15
      • 2015-01-12
      • 1970-01-01
      • 1970-01-01
      • 2023-02-20
      • 1970-01-01
      • 2020-08-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多