import math
x = int(input("Enter a value for x: "))
y = int(input("Enter a value for y: "))
if y == 1 or y == x:
print(1)
if y > x:
print(0)
else:
a = math.factorial(x)
b = math.factorial(y)
div = a // (b*(x-y))
print(div)
这个二项式系数程序有效,但是当我输入两个相同的数字时,它应该等于1,或者当y大于x时,它应该等于0。
答案 0 :(得分:20)
这是一个实际使用correct formula的版本。 :)
#! /usr/bin/env python
''' Calculate binomial coefficient xCy = x! / (y! (x-y)!)
'''
from math import factorial as fac
def binomial(x, y):
try:
binom = fac(x) // fac(y) // fac(x - y)
except ValueError:
binom = 0
return binom
#Print Pascal's triangle to test binomial()
def pascal(m):
for x in range(m + 1):
print([binomial(x, y) for y in range(x + 1)])
def main():
#input = raw_input
x = int(input("Enter a value for x: "))
y = int(input("Enter a value for y: "))
print(binomial(x, y))
if __name__ == '__main__':
#pascal(8)
main()
...
这是我几年前写的binomial()
的替代版本,它不使用math.factorial()
,而旧版本的Python中并不存在def binomial(n, r):
''' Binomial coefficient, nCr, aka the "choose" function
n! / (r! * (n - r)!)
'''
p = 1
for i in range(1, min(r, n - r) + 1):
p *= n
p //= i
n -= 1
return p
。但是,如果r不在范围(0,n + 1)内,则返回1.
{{1}}
答案 1 :(得分:3)
因此,如果您在Python"中搜索"实现二项式系数,那么首先会出现这个问题。第二部分中只有this answer包含一个依赖multiplicative formula的有效实现。该公式执行最小的乘法次数。以下功能不依赖于任何内置插件或导入:
def fcomb0(n, k):
'''
Compute the number of ways to choose $k$ elements out of a pile of $n.$
Use an iterative approach with the multiplicative formula:
$$\frac{n!}{k!(n - k)!} =
\frac{n(n - 1)\dots(n - k + 1)}{k(k-1)\dots(1)} =
\prod_{i = 1}^{k}\frac{n + 1 - i}{i}$$
Also rely on the symmetry: $C_n^k = C_n^{n - k},$ so the product can
be calculated up to $\min(k, n - k).$
:param n: the size of the pile of elements
:param k: the number of elements to take from the pile
:return: the number of ways to choose k elements out of a pile of n
'''
# When k out of sensible range, should probably throw an exception.
# For compatibility with scipy.special.{comb, binom} returns 0 instead.
if k < 0 or k > n:
return 0
if k == 0 or k == n:
return 1
total_ways = 1
for i in range(min(k, n - k)):
total_ways = total_ways * (n - i) // (i + 1)
return total_ways
最后,如果您需要更大的值并且不介意交易一些准确性,Stirling's approximation可能是要走的路。
答案 2 :(得分:2)
对于Python 3,scipy具有scipy.special.comb函数,它可以产生浮点数以及精确的整数结果
import scipy.special
res = scipy.special.comb(x, y, exact=True)
请参阅scipy.special.comb的文档。
对于Python 2,该函数位于scipy.misc中,它的工作方式相同:
import scipy.misc
res = scipy.misc.comb(x, y, exact=True)
答案 3 :(得分:1)
对于if
,您的程序将继续使用第二个y == x
语句,从而导致ZeroDivisionError
。你需要使这些陈述互相排斥;这样做的方法是使用elif
(“else if”)而不是if
:
import math
x = int(input("Enter a value for x: "))
y = int(input("Enter a value for y: "))
if y == x:
print(1)
elif y == 1: # see georg's comment
print(x)
elif y > x: # will be executed only if y != 1 and y != x
print(0)
else: # will be executed only if y != 1 and y != x and x <= y
a = math.factorial(x)
b = math.factorial(y)
c = math.factorial(x-y) # that appears to be useful to get the correct result
div = a // (b * c)
print(div)
答案 4 :(得分:1)
这个怎么样? :)它使用正确的公式,避免math.factorial
并减少乘法运算:
import math
import operator
product = lambda m,n: reduce(operator.mul, xrange(m, n+1), 1)
x = max(0, int(input("Enter a value for x: ")))
y = max(0, int(input("Enter a value for y: ")))
print product(y+1, x) / product(1, x-y)
另外,为了避免大整数算术,你可以使用浮点数,转换
product(a[i])/product(b[i])
到product(a[i]/b[i])
并将上述程序重写为:
import math
import operator
product = lambda iterable: reduce(operator.mul, iterable, 1)
x = max(0, int(input("Enter a value for x: ")))
y = max(0, int(input("Enter a value for y: ")))
print product(map(operator.truediv, xrange(y+1, x+1), xrange(1, x-y+1)))
答案 5 :(得分:1)
这是一个使用条件表达式
递归计算二项式系数的函数def binomial(n,k):
return 1 if k==0 else (0 if n==0 else binomial(n-1, k) + binomial(n-1, k-1))
答案 6 :(得分:1)
由PM 2Ring和alisianoi给出的缩短的乘法变体。适用于python 3,不需要任何软件包。
def comb(n, k):
# Remove the next two lines if out-of-range check is not needed
if k < 0 or k > n:
return None
x = 1
for i in range(min(k, n - k)):
x = x*(n - i)//(i + 1)
return x
或
from functools import reduce
def comb(n, k):
return (None if k < 0 or k > n else
reduce(lambda x, i: x*(n - i)//(i + 1), range(min(k, n - k)), 1))
除法后立即进行除法以不累积高数字。
答案 7 :(得分:0)
我建议使用动态编程(DP)来计算二项式系数。与直接计算相反,它避免了大数的乘法和除法。除递归解决方案外,它还将以前解决的重叠子问题存储在表中,以便快速查找。下面的代码显示了用于计算二项式系数的自下而上(表格)DP和自上而下(内存化)DP实现。
class B: ViewController {
@IBOutlet weak var server: UITextField!
@IBOutlet weak var port: UITextField!
let objA= A()
@IBAction func save(_ sender: Any) {
objA.updateServerAndport(s = server.text!, p : port.text!)
}
}
注意:出于显示目的,备忘录表的大小设置为较小的值(6),如果要计算较大的n和k的二项式系数,则应将其增加。
答案 8 :(得分:0)
最好采用递归定义,如Vadim Smolyakov的回答,并结合DP(动态编程),但是对于后者,您可以从模块functools应用lru_cache装饰器:
import functools
@functools.lru_cache(maxsize = None)
def binom(n,k):
if k == 0: return 1
if n == k: return 1
return binom(n-1,k-1)+binom(n-1,k)
答案 9 :(得分:0)
最简单的方法是使用乘法公式。按预期,它适用于(n,n)和(n,0)。
def coefficient(n,k):
c = 1.0
for i in range(1, k+1):
c *= float((n+1-i))/float(i)
return c
答案 10 :(得分:0)
请注意,从Python 3.8
开始,标准库提供了math.comb
函数来计算二项式系数:
math.comb(n,k)
这是从n个项目中选择k个项目而无需重复的方式的数量
n! / (k! (n - k)!)
:
import math
math.comb(10, 5) # 252
math.comb(10, 10) # 1
答案 11 :(得分:0)
对于寻找二项式系数的 log (Theano称为binomln
)的每个人,this answer都有:
from numpy import log
from scipy.special import betaln
def binomln(n, k):
"Log of scipy.special.binom calculated entirely in the log domain"
return -betaln(1 + n - k, 1 + k) - log(n + 1)
(而且,如果您的语言/图书馆缺少betaln
但拥有gammaln
(如Go),则不必担心,因为{{3} }。