[英]Efficient algorithm to solve (m choose x) = n in python
Given 特定
m : number of posters to design m :要设计的海报数量
n : total number of available colors n :可用颜色总数
solve for 解决
x : number of colors for each poster so that each poster has a unique combination of colors x :每个海报的颜色数,以便每个海报具有唯一的颜色组合
subject to the equation 服从等式
(n choose x) = m (n选择x)= m
I have coded the above problem in python and the source code is given below 我已经在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))
The above solution will only work for small integers but I need a solution to work for larger numbers, eg when n = 47129212243960. 上面的解决方案仅适用于小整数,但是我需要一个解决方案来处理较大的数字,例如,当n = 47129212243960时。
Is there any efficient way to solve this? 有什么有效的方法可以解决这个问题吗?
Since (n choose x) == (n choose (nx))
, and it seems like you want to find the minimal x
, we can search for x
between 0
and n/2
. 由于(n choose x) == (n choose (nx))
,似乎您想找到最小的x
,我们可以在0
到n/2
之间搜索x
。 Also, for arbitrary n
and m
, it's possible no such x
exists, but probably what you want is the minimal such x
, if one exists, such that (n choose x) >= m
, ie the smallest x
guaranteeing you can make m
unique colour combinations -- with that x
you may even be able to make more than m
unique colour combinations. 另外,对于任意的n
和m
,可能不存在这样的x
,但可能想要的是最小的x
,如果存在的话,那么(n choose x) >= m
,即保证您可以使m
最小的x
独特的颜色组合-使用x
您甚至可以制作超过m
独特的颜色组合。
There's a simple O(n) solution, using the fact that (n choose (x+1)) / (n choose x) == (nx)/(x+1)
, which you can see by expanding the "choose" expressions in terms of factorials, and cancelling things out. 有一个简单的O(n)解决方案,使用(n choose (x+1)) / (n choose x) == (nx)/(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))
This prints: 打印:
4
-1
4
3
3
1
3
4
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.