【发布时间】:2021-09-18 15:49:16
【问题描述】:
我正在编写这个程序,它需要 54 (num1) 个数字并将它们放在一个列表中。然后它取其中的 16 (num2) 个数字并形成一个列表,其中包含从 "num1"c"num2" 的所有可能组合中选择的 16 个数字的列表。然后它会获取这些列表并生成 4x4 数组。
我的代码可以运行,但是运行 54 个数字来获取我想要的所有数组需要很长时间。我知道这一点是因为我已经使用 20 到 40 个数字测试了代码并对其进行了计时。
20 numbers = 0.000055 minutes
30 numbers = 0.045088 minutes
40 numbers = 17.46944 minutes
使用我得到的所有 20 点测试数据,我建立了一个数学模型来预测运行 54 个数字需要多长时间,我得到 1740 分钟 = 29 小时。这已经是对预测 38 小时的代码 v1 和实际上使我的机器崩溃的 v0 的改进。
我正在与您联系,以尝试使此运行更快。该程序甚至不是 RAM 密集型的。我有 8GB 的 RAM 和核心 i7 处理器,它根本不会减慢我的机器速度。与我以前的版本相比,它实际上运行非常流畅,我的电脑甚至崩溃了几次。
你们觉得有办法吗?我目前正在抽样以减少处理时间,但如果可能的话,我宁愿不抽样。我什至没有打印数组以减少处理时间,我只是打印一个计数器来查看我生成了多少组合。
这是代码:
import numpy as np
import itertools
from itertools import combinations
from itertools import islice
from random import sample
num1 = 30 #ideally this is 54, just using 30 now so you can test it.
num2 = 16
steps = 1454226 #represents 1% of "num1"c"num2" just to reduce processing time for testing.
nums=list()
for i in range(1,num1+1):
nums.append(i)
#print ("nums: ", nums) #Just to ensure that I am indeed using numbers from 1 to num1
vun=list()
tabl=list()
counter = 0
combin = islice(itertools.combinations(nums, num2),0,None,steps)
for i in set(combin):
vun.append(sample(i,num2))
counter = counter + 1
p1=i[0];p2=i[1];p3=i[2];p4=i[3];p5=i[4];p6=i[5];p7=i[6];p8=i[7];p9=i[8]
p10=i[9];p11=i[10];p12=i[11];p13=i[12];p14=i[13];p15=i[14];p16=i[15]
tun = np.array ([(p1,p2,p3,p4),(p5,p6,p7,p8),(p9,p10,p11,p12),(p13,p14,p15,p16)])
tabl.append(tun)
# print ("TABL:" ,tabl)
# print ("vun: ", vun)
print ("combinations:",counter)
我用这段代码得到的输出是:
combinations: 101
理想情况下,该数字应为 2.109492366(10)¹³ 或至少 1%。只要它运行 54x16 并且不需要 29 小时。
【问题讨论】:
-
通过将 54 个数字放入一个列表中,然后取其中的 16 个等,您想达到什么目标?
-
@chepner 不是指数级的。只需 O(n^k)。
-
在 RAM 中存储大量数据。说 “该程序甚至不是 RAM 密集型的。”
-
21 万亿个长度为 16 的列表涉及超过 250 万亿个数字。如果您想在普通计算机上处理这么多数据,那么一天多一点就完成了。
-
仍然想知道代码的用途。我害怕对学习真正的用例感到失望......
标签: python performance combinations itertools