用Python划分数论
给定一个整数,计算表示总数的可能方法数。 所需和为5,整数可被视为[1,2,3] 实现目标总和的5种方法是:用Python划分数论,python,itertools,Python,Itertools,给定一个整数,计算表示总数的可能方法数。 所需和为5,整数可被视为[1,2,3] 实现目标总和的5种方法是: 1 + 1 + 1 + 1 + 1 = 5 1 + 1 + 1 + 2 = 5 1 + 2 + 2 = 5 1 + 1 + 3 = 5 2 + 3 = 5 输入为5,3,其中3是达到总数5的范围[1,2,3] 输出为5我认为在这里使用combinations()不起作用-该函数返回传递给它的数组的组合,但不会创建任何给定元素的副本。您可以通过使用带有替换()的变体combina
1 + 1 + 1 + 1 + 1 = 5
1 + 1 + 1 + 2 = 5
1 + 2 + 2 = 5
1 + 1 + 3 = 5
2 + 3 = 5
输入为5,3,其中3是达到总数5的范围[1,2,3]
输出为5我认为在这里使用
combinations()
不起作用-该函数返回传递给它的数组的组合,但不会创建任何给定元素的副本。您可以通过使用带有替换()的变体combinations\u来解决这个问题,但即使这样,您最终也会遇到过多的无效组合,对于冗长的列表,运行时也会变得棘手
而应考虑如下递归解决方案:
def reps(target, nums):
res = []
for i, v in enumerate(nums):
if target - v > 0:
res += [[v] + l for l in reps(target-v, nums[i:])]
elif target - v == 0:
res += [[v]]
return res
这里我取一个目标和一个数字列表,然后尝试从目标中减去每个数字。如果差正好等于0,我将最后一个值添加到列表中。如果大于零,我将继续尝试使用新的目标值调用reps()
,将元素添加到列表中,并使用原始数字的子集防止相同答案的排列。我将所有这些组合在一起,从列表中预先添加先前选择的值,并以这种方式继续,直到构建了所有组合的列表
示例target=5
和nums=[1,2,3]
-
[[1, 1, 1, 1, 1], [1, 1, 1, 2], [1, 1, 3], [1, 2, 2], [2, 3]]
因为你的问题只需要可能性的数量,而不需要可能性本身,所以这是最快的方法之一:
def partitions(n, m):
if n <= 1:
return 1
if m > n:
return partitions(n, n)
total = 0
for i in range(1, m + 1):
total += partitions(n - i, i)
return total
检查有关Itertools()的文档。您会发现组合需要两个参数。2+2+2=5
Huh?错误TypeError:Required argument'r'(pos 2)找不到
可以自行理解。你在哪里被卡住了?@RoadRunner不完全是。从那里得到的解决方案不会得到预期的答案。我已经检查过了。@Tomothy32可能是重复的,这是因为范围(10)
包括0
,并且在0
之后添加0
有无限多的解决方案。如果范围不包括[1,m]
,而是类似于[1,3,17]
。原来的问题没有说明数字必须是连续的。@DillonDavis说输入是5,3,输出是5。这就是我认为他需要的。@Tomothy32你能解释一下吗program@Maws这与其说是一个程序,不如说是一个数学算法。我建议你看看这篇文章。
In [1]: def partitions(n, m):
...: if n <= 1:
...: return 1
...: if m > n:
...: return(partitions(n, n))
...:
...: total = 0
...: for i in range(1, m + 1):
...: total += partitions(n - i, i)
...:
...: return total
...:
In [2]: partitions(5, 3)
Out[2]: 5
In [3]: partitions(10, 5)
Out[3]: 30
In [4]: partitions(50, 30)
Out[4]: 202139 # returned in less than a second