【问题标题】:Efficient algorithm to solve (m choose x) = n in pythonpython中解决(m选择x)= n的高效算法
【发布时间】:2015-10-25 16:43:38
【问题描述】:

给定

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.

有什么有效的方法解决这个问题吗?

【问题讨论】:

  • 如果您可以使用阶乘的近似值(并且不需要确切的值),您可以使用stirling's approximation
  • (n 选择 x) 为 0、1 或至少为 n,因此如果 n 为 47129212243960,那么您将至少需要设计 47 万亿张海报。您的问题是否有错误,或者这只是一个理论上的难题?
  • 你应该使用//整数除法。此外,数学模块中有一个有效的阶乘函数。但是,您的循环直接计算 (n 选择 r) 序列会更快,而不是通过阶乘(每次使用 math.factorial 计算或使用存储在列表中的值)。
  • 另外,如果您的 ColorChoice 函数没有得到完全匹配,它将无法找到 i。那是你真正想要的吗?如果不是,请考虑将 == 更改为 >=
  • here 提出了类似的问题。有一些想法。

标签: python algorithm permutation


【解决方案1】:

由于(n choose x) == (n choose (n-x)),并且您似乎想找到最小的x,我们可以在0n/2之间搜索x。此外,对于任意nm,可能不存在这样的x,但可能你想要的是最小的x,如果存在的话,比如(n choose x) >= m,即最小的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

【讨论】:

  • 感谢您提供简单的解决方案。
  • n_choose_x >= m 应该是 n_choose_x == m。因为如果我们使用 m= 221 和 n = 11 的情况,那么 n_choose_x >= m 条件将不起作用
  • @Amit m= 221 和 n = 12
  • 如此整洁 - 太棒了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-18
相关资源
最近更新 更多