我对python很新,我有一个问题,我在试图计算一个等式有多少解,例如Ta + Nb + Mc + Pd = e,其中输入e。我不关心解决方案是什么,只关心数量。
Abcd是可变正整数,NMPT是固定整数
我知道这是一个新手错误,但我尝试了4个嵌套for循环,它花了太长时间,所以我放弃了,但想不出更优雅的方式。即使我从允许循环中消除了潜在的数字,我仍然得到了更大的计算时间。
我已经读过关于生成器花费的时间少得多,但我不确定如何正确使用它们,我设法将时间缩短到一两分钟,但希望更快地使用带有yield的函数。
有点像,不完全是这样,但在这个程度上,是的,我知道嵌套循环是不利的,但我是一个新手,并试图学习。
def function():
count = 0
for a is in range (0,e)
for b is in range (0,int(e/N))
Another for loop
Another for loop
count += 1
yield count
输出它,它给了我更快的结果,但不够快。
或者我是以完全错误的方式思考这个问题?
由于
答案 0 :(得分:1)
这是一类问题,其中更好的算法将比改变代码的工作方式产生更好的性能提升。
所以问题是,T
,N
,M
,P
和e
会找到有多少解决方案。
现在像yield
这样的东西适用于需要所有解决方案的情况......获取所有解决方案将涉及枚举所有解决方案,这将是4个嵌套循环... { {1}}可以为这种情况提供帮助。
计算解决方案使我们能够找到减少行走所需的技巧......
让我们从最外层的循环开始
yield
范围有多高?我们知道,要使解决方案有效,for a in range(1, ?)
,a
,b
和c
必须为正,即d
所以我们可以如果>= 1
,则a
值最高...因此T*a + N*1 + M*1 + P*1 == e
的上限为a
int((e - N - M - P) / T)
for a in range(1, int((e - N - M - P) / T))
for b in range(1, ?)
的范围有多高?我们知道我们已经b
......
T*a
for a in range(1, int((e - N - M - P) / T))
for b in range(1, int((e - T*a - M - P) / N))
for c in range(1, ?)
的范围有多高?同样的原则......
c
现在在这一点上你可能想要做另一个 for循环...但是这里我们需要聪明,如果我们可以避免最后一个循环...因为上限该范围实际上是有效解决方案的数量!
for a in range(1, int((e - N - M - P) / T))
for b in range(1, int((e - T*a - M - P) / N))
for c in range(1, int((e - T*a - N*b - P) / M))
?
这是一种优越的算法,因为它具有更少的循环,因此会更快地返回......
哦,但还有更多...如果你知道数学,如果我没记错,你当然可以删除另一个循环,如果不能删除所有这些...但这是你需要实际知道数学而不仅仅是强制解决方案
答案 1 :(得分:1)
加速嵌套for循环的常用方法是使用itertools.product()生成所有参数值,itertools.starmap()将参数应用于函数:
而不是:
for a in range(5):
for b in range(8):
for c in range(10, 17):
for d in range(5, 11):
v = f(a, b, c, d)
...
改为写下:
for v in starmap(f, product(range(5), range(8), range(10,17), range(5,11))):
...
好处是: