在python中解决(m选择x)= n的高效算法

时间:2015-10-25 07:34:01

标签: python algorithm permutation

给出

  

m :设计的海报数量
   n :可用颜色总数

解决

  

x :每张海报的颜色数量,以便每张海报都有独特的颜色组合

受等式

的影响
  

(n选择x)= m

我在python中编写了上面的问题,源代码在下面给出

factorial = []

def generateList(n):
    factorial.append(1)
    factorial.append(1)

    for i in range(2,n+1):
        factorial.append(i * factorial[i-1])

def calculateFac(n,i):
    return int((factorial[n]) / (factorial[i] * factorial[n-i]))

def ColorChoice(m,n):
    for i in range(1,int(n/2)+1):
        if m == calculateFac(n,i):
            return i
    return -1

def checkChoose(m,n):
    generateList(n)
    return ColorChoice(m,n)

print (checkChoose(35,7))

上述解决方案仅适用于小整数,但我需要一个解决方案来处理更大的数字,例如当n = 47129212243960。

有没有有效的方法来解决这个问题?

1 个答案:

答案 0 :(得分:2)

(n choose x) == (n choose (n-x))以来,您似乎想要找到最小x,我们可以在x0之间搜索n/2。此外,对于任意nm,可能没有这样的x存在,但可能你想要的是最小的x,如果存在,那么(n choose x) >= m 1}},即最小的x,保证您可以使用m独特的颜色组合 - 使用x您甚至可以制作超过m个唯一颜色组合

有一个简单的O(n)解决方案,使用(n choose (x+1)) / (n choose x) == (n-x)/(x+1)这个事实,你可以通过扩展因子的“选择”表达式来解决这个问题,并取消一些事情。

def x(m,n):
    n_choose_x = 1
    for x in xrange(1, n/2 + 1):
        n_choose_x = n_choose_x * (n+1-x) / x
        if n_choose_x >= m:
            return x
    return -1

print(x(70,8))
print(x(71,8))
print(x(57,8))
print(x(56,8))
print(x(55,8))
print("")
print(x(9999999, 47129212243960))
print(x(99999999471292122439609999999, 47129212243960))
print(x(99999999947129212243960999999471292122439609999999, 47129212243960))

打印:

4
-1
4
3
3

1
3
4