所以我有一个Python 3脚本,以下列方式计算组合
def permutate(n, k):
if k == 0:
return 1
elif n < n - k + 1:
return n
else:
return n * permutate(n - 1, k - 1)
def choose(n, k):
if k > n / 2:
k = n - k
return int(permutate(n, k) / permutate(k, k))
所以我的问题是在处理大数字时,
choose(5, 3)
产生10这是正确的。
choose(1000, 1)
choose(52, 4)
choose(1000, 5)
choose(1000, 999)
这些都会产生正确的结果,但是当我尝试传递
时choose(1000, 800)
我得到了错误的结果,我得到的整数的一部分的头是正确的,但是当我到达整数的尾部时它是不正确的,这让我相信问题在于Python试图处理除法选择函数中两个非常大的数字。
return int(permutate(n, k) / permutate(k, k))
对不起,如果我违反了任何规则,或者代码格式化方式如何,正式是我的第一篇帖子:)
答案 0 :(得分:3)
问题是:你的所有分区都使用浮点数,而它们显然是整数。
Python 3与Python 2的行为不同。
3/2 => 1.5
3//2 => 1
将/
替换为//
(无需像你一样转换整数)
return permutate(n, k) // permutate(k, k)
也在这里(不太重要)
if k > n // 2
答案 1 :(得分:2)
这是另一个解决方案,它使用fractions模块(通过减少到最低项)来进行除法。它还使用了这样的事实: choose(100,70) = choose(100,30)
以便不做不必要的乘法:
from fractions import Fraction
def choose(n,k):
if k > n//2: k = n - k
p = Fraction(1)
for i in range(1,k+1):
p *= Fraction(n - i + 1, i)
return int(p)
例如,
>>> choose(10000,100)
65208469245472575695415972927215718683781335425416743372210247172869206520770178988927510291340552990847853030615947098118282371982392705479271195296127415562705948429404753632271959046657595132854990606768967505457396473467998111950929802400
(可以用计算机代数系统验证)。
速度相当快,需要大约一秒才能找到choose(10**9, 10000)
的所有54341位数字。
答案 2 :(得分:0)
编辑正确/简洁
我有另一种方法可以减轻分裂的负担,并将其放在乘法上。我建议利用组合的定义。由于组合和排列是计数技术,因此通过算术运算失去精度并不是很好的工艺。
在组合中,你想尽可能地取消分子和分母中的公因子,以便你可以。所以我说完全抛弃了你的排列函数,你的组合函数就像... ...
def permute(n, k):
// P(n,k) = n!/(n-k)! mathematically
largest_dividable_number = max(k, n-k)
output_value = 1
starting_value = n
for i in range(1,largest_dividable_number - 1):
output_value = output_value * starting_value
starting_value = starting_value - 1
return output_value
def choose(n, k):
p = permute(n,k)
return p//math.factorial(k)