繁体   English   中英

Python - 如何减少大 O 并提高多个嵌套 for 循环的效率?

[英]Python - How to decrease big O and increase efficiency in multiple nested for loops?

我写了一个 python 脚本,它计算满足以下条件的所有可能性:

  1. a^(2) + b^(2) + c^(2) + d^(2) + e^(2) = f^(2)
  2. a,b,c,d,e,f 是不同的非零整数
  3. a,b,c,d,e 是孪生素数之间的偶数(例如 11 和 13 是孪生素数,因此 12 是有效的可能性)
  4. f≤65535
  5. a 的位数之和 == b 的位数之和 == c 的位数之和 == d 的位数之和 == e 的位数之和 == 位数之和离开

我不肯定当包括标准5时是否会有任何结果,但我想至少及时发现。 理想情况下,还应满足以下条件:

  1. 对 a,b,c,d,e,f 使用相同值但顺序不同的结果不应出现在结果中; 理想情况下,它们也应该从 for 循环中排除
  2. 结果应按 a 的最小值排序,b 的最小值排序,依此类推

我的问题是,我怎样才能减少操作时间并提高效率?

import itertools
import time

start_time = time.time()

def is_prime(n):
    for i in range(2, n):
        if n % i == 0:
            return False
    return True

def generate_twin_primes(start, end):
    for i in range(start, end):
        j = i + 2
        if(is_prime(i) and is_prime(j)):
            n = text_file2.write(str(i+1) + '\n')

def sum_digits(n):
   r = 0
   while n:
       r, n = r + n % 10, n // 10
   return r

def is_sorted(vals):
    for i in range(len(vals)-2):
        if vals[i] < vals[i+1]:
            return False
    return True

def pythagorean_sixlet():
    valid = []
    for a in x:
        for b in x:
            for c in x:
                for d in x:
                    for e in x:
                        f = (a * a + b * b + c * c + d * d + e * e)**(1/2)
                        if f % 1 == 0 and all(x[0]!=x[1] for x in list(itertools.combinations([a, b, c, d, e], 2))):
                            if sum_digits(a) == sum_digits(b) == sum_digits(c) == sum_digits(d) == sum_digits(e) == sum_digits(int(f)):
                                valid.append([a, b, c, d, e, int(f)])
    for valid_entry in valid:
        if is_sorted(valid_entry):
            with open("output.txt", "a") as text_file1:
                text_file1.write(str(valid_entry[0]) + " " + str(valid_entry[1]) + " " + str(valid_entry[2]) + " " + str(valid_entry[3]) + " " + str(valid_entry[4]) + " | " + str(valid_entry[5]) + '\n')
                text_file1.close()

#input #currently all even numbers between twin primes under 1000
text_file2 = open("input.txt", "w")
generate_twin_primes(2, 1000)
text_file2.close()

# counting number of lines in "input.txt" and calculating number of potential possibilities to go through
count = 0
fname = "input.txt"
with open(fname, 'r') as f:
    for line in f:
        count += 1
print("Number of lines:", count)
print("Number of potential possibilites:", count**5)

with open('input.txt', 'r') as f:
    x = f.read().splitlines()
    x = [int(px) for px in x]

pythagorean_sixlet()
print("--- %s seconds ---" % (time.time() - start_time))

嗯,这闻起来很像硬件问题,所以我们不能轻易放弃农场...... :)

需要考虑的几件事:

  1. 如果你想检查独特的组合,可能性的数量会从count**5减少很多,对吧?
  2. 您正在循环的最里面进行所有检查。 您能否在此过程中进行一些检查,以便您不必生成和测试所有可能性,这是“昂贵的”。
  3. 如果您确实选择在内部检查唯一性,请找到一种更好的方法来制作所有组合……这太贵了。 提示:如果你制作了一组你拥有的数字,它会告诉你什么?

实现上述一些:

Number of candidate twin primes between [2, 64152]: 846

total candidate solutions: 1795713740 [need to check f for these]
elapsed:  5.957056045532227

size of result set: 27546
20 random selections from the group:
(40086.0, [3852, 4482, 13680, 20808, 30852])
(45774.0, [6552, 10458, 17028, 23832, 32940])
(56430.0, [1278, 13932, 16452, 27108, 44532])
(64746.0, [15732, 17208, 20772, 32562, 46440])
(47610.0, [3852, 9432, 22158, 24372, 32832])
(53046.0, [3852, 17208, 20772, 23058, 39240])
(36054.0, [4518, 4932, 16452, 21492, 22860])
(18396.0, [3258, 4518, 5742, 9342, 13680])
(45000.0, [2970, 10890, 16650, 18540, 35730])
(59976.0, [2970, 9342, 20772, 35802, 42282])
(42246.0, [3528, 5652, 17208, 25308, 28350])
(39870.0, [3528, 7308, 16362, 23292, 26712])
(64656.0, [8820, 13932, 16452, 36108, 48312])
(61200.0, [198, 882, 22158, 35532, 44622])
(55350.0, [3168, 3672, 5652, 15732, 52542])
(14526.0, [1278, 3528, 7128, 7560, 9432])
(65106.0, [5652, 30852, 31248, 32832, 34650])
(63612.0, [2088, 16830, 26730, 33750, 43650])
(42066.0, [2088, 13932, 15642, 23832, 27540])
(31950.0, [828, 3582, 13932, 16452, 23292])
--- 2872.701852083206 seconds ---
[Finished in 2872.9s]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM