【发布时间】:2016-09-19 08:57:09
【问题描述】:
我需要根据某些限制条件找出最佳的媒体选择。我在四个嵌套的 for 循环中执行此操作,因为它需要大约 O(n^4) 次迭代,所以速度很慢。我一直试图让它更快,但它仍然很慢。我的变量可能高达几千。
这是我正在尝试做的一个小例子:
max_disks = 5
max_ssds = 5
max_tapes = 1
max_BR = 1
allocations = []
for i in range(max_disks):
for j in range(max_ssds):
for k in range(max_tapes):
for l in range(max_BR):
allocations.append((i,j,k,l)) # this is just for example. In actual program, I do processing here, like checking for bandwidth and cost constraints, and choosing the allocation based on that.
每种媒体类型多达数百个并不慢,但会减慢数千个。
我试过的其他方法是:
max_disks = 5
max_ssds = 5
max_tapes = 1
max_BR = 1
allocations = [(i,j,k,l) for i in range(max_disks) for j in range(max_ssds) for k in range(max_tapes) for l in range(max_BR)]
这样即使是这么小的数字也很慢。
两个问题:
- 为什么第二个对于小数字来说很慢?
- 如何使我的程序适用于大数字(以千计)?
这是带有 itertools.product 的版本
max_disks = 500
max_ssds = 100
max_tapes = 100
max_BR = 100
# allocations = []
for i, j, k,l in itertools.product(range(max_disks),range(max_ssds),range(max_tapes),range(max_BR)):
pass
完成这些数字需要 19.8 秒。
【问题讨论】:
-
第一个具有列表理解的示例比第二个示例快。它们在其他方面是等效的,但
allocations.append属性查找和后续方法调用会减慢嵌套循环。您可能想在这里查看itertools.product(),并避免使用所有可能的组合创建一个巨大的列表对象(而是一个一个地处理项目)。 -
我也试过 itertools.product() 。但这对数千人也不起作用。
-
你坚持要建立一个分配列表吗?您已经知道要构建的列表的一般结构,所以您不能单独处理分配吗?
-
添加到我在这里使用的列表中只是一个例子。实际上,在最里面的循环中,我正在执行诸如检查分配提供的带宽之类的操作,并决定是否保留分配。
-
@Pretty: '没用' 但是什么也没告诉我们。
itertools.product()仍然比您发布的任何一种方法都快,并且如果您不首先将所有内容都具体化到列表中,那么它是无与伦比的。也许您想展示还有什么您正在使用您生成的组合做什么?为什么首先需要在列表中生成这么多的元组?
标签: python performance linear-programming constraint-programming