[英]“For y in range(1,x)” loops taking too long to run. How can one expedite this process in Python?
此代码需要40秒钟才能以1000的订单运行。我需要在order = 100,000,000时运行它。 有没有办法让我加快这段代码的速度?
from fractions import Fraction
x=5
order=1000
count=0
while x <=order:
for y in range(1,x):
if str(Fraction(y/x).limit_denominator()) != "%s/%s"%(y,x):
print(Fraction(y/x).limit_denominator())
count += 1
print(" ")
x+=1
count= (count + 1) * 6 + (order -1)*6
print(count)
这段代码的目的是破译Euler项目上的问题351。 我对Python的了解有限,因此我尝试用我所知道的来弄清楚它。 最初,我发现每行隐藏的绿色点都很容易找到( (n-1)* 6
),但是确定中心点是一个更大的挑战。 找出每个受阻绿点的图案不是线性的,而是要考虑将六个当前三角形中的每个三角形的行视为分数,然后找到可以简化的分数。 此代码解析三角形的每个“行”以简化分数。 如果找到一个,则代码将1加到变量'count'。 由于while循环从第5行开始(在第一个绿色点之后1行),我不得不将这些点添加回末尾的最终计数( (count + 1)* 6
)。 我使用此代码来确认找到的绿点数量大约为1000。不过运行了40秒。 截至2018年1月11日美国东部标准时间(EST),我已经在计算机上运行1亿天半了,这100,000,000可能需要更长的时间(从几天到几周。)
正如其他人所提到的,您的算法具有很差的复杂度,但是您也使用Fraction
错误。 使用两个参数的版本,并且绝对不要转换和比较字符串。 您也没有充分的理由两次构造和调用Fraction(y/x).limit_denominator()
。
这将极大地加快代码的速度,但是并不能解决算法的复杂性:
order = 1000
x = 5
count = 0
while x <= order:
for y in range(1, x):
frac = Fraction(y, x) # don't use y/x
if frac.numerator != y:
# print(frac) # if you *must* print, reuse this
count += 1
# print(" ")
x += 1
count = (count + 1) * 6 + (order - 1) * 6
print(count)
问题不是Python; 这是你的算法。
要分析运行时解决方案,首先需要使自己熟悉渐近复杂性 ,通常用Big-O表示法进行描述。
Big-O表示法描述了运行时间如何随着输入n
的大小的变化而变化( O(n)
)。
下面是带有示例的常见Big-O运行时:
O(1)-运行时不依赖于数组的大小(无论大小都恒定时间)。
int myarray[] = //fill array with values
cout << myarray.length;
O(N)-运行时间与数组大小成正比。
int myarray[] = //fill array with values
for(int i = 0; i<n; i++) cout << myarray[i] << " ";
O(N ^ 2)-运行时间与数组的平方大小成正比。
int myarray[] = //fill array with values
for(int i = 0; i<n; i++) {
for(int j = 0; j<n; j++) {
cout << myarray[i]+myarray[j] << endl;
//print the sum of every possible pairing of digits in array (with repeats)
因此,如果我们知道O(n)
运行时,我们就能预测算法要花多长时间才能运行。 您的算法为O(n ^ 2),因为它使用while循环迭代到1000(n),而第二个嵌套的for循环迭代直到x。 我们无视for循环最多迭代x,因为它不是渐近有效的。
现在我们看到您的算法太慢了。 100,000,000 ^ 2是一个很大的数字,因此必须改进您的算法。
请注意, O(n*logn)
的运行时将导致800,000,000(n = 100,000,000),这将在大约10秒内运行(给定或取决于常量因素,语言等),这是更加合理的。
根据问题的不同,如果您对存储数据的方式很聪明,甚至可以减少算法以线性时间( O(n)
)运行。 无论哪种方式,您当前的算法都太慢了。 回到绘图板!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.