如何使用python解决组合问题?
Posted
技术标签:
【中文标题】如何使用python解决组合问题?【英文标题】:How to use python to solve a combination problem? 【发布时间】:2022-01-11 23:18:30 【问题描述】:我想解决一个组合问题。给定一个变量列表,我想获得由这些变量组成的具有给定顺序的所有多项式项。例如,对于给定的数字列表 [x1, x2, x3]
和 2 的顺序,该函数应返回 [x1^2, x1*x2, x1*x3, x2^2, x2*x3, x3^2]
的列表;对于给定的数字列表 [x1, x2]
和 3 的顺序,该函数应返回 [x1^3, x1^2*x2, x1*x2^2, x2^3]
的列表
如果我在第一个示例中使用 for 循环,代码将如下所示:
for i in range(given_order+1):
for j in range(given_order+1-i):
for k in range(given_order+1-j-i):
list.append(x1^i*x2^j*x3^k)
但是给定列表的长度和给定的顺序都不是固定的,所以for循环的数量是不确定的。我试图使用递归来解决它,但失败了。有人可以帮我解决这个问题吗?
【问题讨论】:
你试过for (a1, a2, ..., an) in itertools.permutations([x1, x2, ..., xn], r=n): list.append(a1 * a2 * ... * an)
吗?
@Green Cloak Guy。感谢您的提示,itertools.combinations_with_replacement 可以解决问题。
【参考方案1】:
您可以使用mathmatical induction 编写poly(t, order)
-
-
如果输入
t
为空,则停止迭代
(归纳)至少有一个t
。如果order
小于一,则没有什么可以展开,返回空多项式
(归纳)至少有一个t
,而order
至少是一个。
要在组合中包含第一个元素,对于子问题(t, order - 1)
中的所有p
,将t[0]
前置到p
和yield
要生成没有第一个元素的所有组合,只需在子问题(t[1:], order)
上重复
def poly(t, order):
if not t:
return #1
elif order < 1:
yield () #2
else:
for p in poly(t, order - 1): #3
yield (t[0], *p)
yield from poly(t[1:], order)
与order = 2
-
for p in poly(('x', 'y', 'z'), 2):
print("*".join(p))
x*x
x*y
x*z
y*y
y*z
z*z
与order = 3
-
for p in poly(('x', 'y', 'z'), 3):
print("*".join(p))
x*x*x
x*x*y
x*x*z
x*y*y
x*y*z
x*z*z
y*y*y
y*y*z
y*z*z
z*z*z
上面我们使用"*".join(p)
以可读的方式格式化多项式。但是,您可以编写 format
函数将 (x, x)
转换为 x^2
和 (x, z, z)
转换为 x*z^2
-
def format(p):
mem = dict()
for x in p:
mem[x] = mem[x] + 1 if x in mem else 1
return "*".join(x if e == 1 else f"x^e" for (x,e) in mem.items())
for p in poly(('x', 'y', 'z'), 3):
print(format(p))
x^3
x^2*y
x^2*z
x*y^2
x*y*z
x*z^2
y^3
y^2*z
y*z^2
z^3
【讨论】:
【参考方案2】:不要拿走@Mulan 非常优雅的答案,但已经有一个内置函数可以代替:
import itertools
order = 3
var = ['x', 'y', 'z']
c = itertools.combinations_with_replacement(var, order)
for i in c:
print(i)
【讨论】:
以上是关于如何使用python解决组合问题?的主要内容,如果未能解决你的问题,请参考以下文章