如何避免Python中的内存错误,同时通过来自另一个列表中的大量排列来ziping列列表以获取唯一的组合?
我有以下代码来生成卡车和三位数排列之间的所有独特组合。我(下)的方式给了我正确的结果。但是,只有在Len(Tripares)&Lt时才起作用; 10。 11我遇到了一个内存错误。有没有办法避免此内存错误?
import itertools
from itertools import cycle
trucks=['A','B','C']
tripares = ['trip1', 'trip2', 'trip3', 'trip4', 'trip5', 'trip6', 'trip7', 'trip8', 'trip9', 'trip10', 'trip11', 'trip12']
# Get all permutations of the tripares list
perms = itertools.permutations(tripares,len(tripares))
# Zip the two lists and cycle the trucks list so all trips are matched with a truck
combinations = [list(zip(cycle(trucks), x)) for x in perms]
# Drop duplicates to get unique values
combs_unique = set([tuple(sorted(x)) for x in combinations ])
print(len(combs_unique))
# Should print 34650
I have the code below to generate all unique combinations between trucks and the permutations of tripares. The way I do it (below) gives me correct results. However it works only when len(tripares) < 10. When len(tripares) > 11 I get a memory error. Is there a way to avoid this memory error?
import itertools
from itertools import cycle
trucks=['A','B','C']
tripares = ['trip1', 'trip2', 'trip3', 'trip4', 'trip5', 'trip6', 'trip7', 'trip8', 'trip9', 'trip10', 'trip11', 'trip12']
# Get all permutations of the tripares list
perms = itertools.permutations(tripares,len(tripares))
# Zip the two lists and cycle the trucks list so all trips are matched with a truck
combinations = [list(zip(cycle(trucks), x)) for x in perms]
# Drop duplicates to get unique values
combs_unique = set([tuple(sorted(x)) for x in combinations ])
print(len(combs_unique))
# Should print 34650
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您只想要唯一组合的数字,则可以简单地计算它,而无需生成所有这些大序列。
让我们以您的榜样输入。第一辆卡车将有4次旅行中有4辆(无卡车旅行 /否卡车):相当于
12! / 8! / 4! = 495
。然后,第二辆卡车将进行剩下的8次旅行中的4次:8! / 4! / 4! = 70
。第三辆卡车进行了最后4次旅行:4! / 0! / 4! = 1
。因此总数为495 * 70 * 1 = 34650
您可以使用这样的代码:
编辑:如果需要实际组合,则获取组合
,而不仅仅是它们的数字,您可以一次通过递归来“手动”中的代码生成它们:列出第一辆卡车的所有旅行的连击,附加到每个卡车的每个旅行中,第二辆卡车剩余的旅行的连击列表和因此,直到卡车只剩下一个可能的组合。这使用了合理的内存,并且也不像人们期望的那样慢:
我在18次旅行/3辆卡车(17153136连击)和16/4(63063000连击)上对其进行了测试。在后一种情况下,我的PC上花费了大约275秒。
(注意:我只是为每个组合返回元组旅行,而无需将其添加到卡车上 subtuples中。只需考虑第一个
ntrips // ntrucks
元素属于第一辆卡车,依此类推)。优化
由于您想提取最佳组合,为什么要生成全部,然后进行计算?从上面的代码开始,一旦获得每个组合,就可以很容易地计算每个组合的消耗,将其与当前最佳的最佳选择,并且只能跟踪新的最佳状态,甚至不维护巨型列表。
这种方法甚至可以让您进行一些前进检查,在之前丢弃组合,然后完全定义它,从而大大加快执行力。
If you just want the number of unique combinations you can simply compute it, without generating all those big sequences.
Let's take your example input. The first truck will have 4 (no of trips / no of trucks) of the 12 trips: it amounts to
12! / 8! / 4! = 495
. Then the second truck will have 4 of the remaining 8 trips:8! / 4! / 4! = 70
. The third truck takes the last 4 trips:4! / 0! / 4! = 1
. So the total count is495 * 70 * 1 = 34650
You may use a code like this:
EDIT: get the combinations
If you need the actual combinations, not just their number, you can generate them in your code "manually", one at a time, via recursion: list the combos for all trips for the first truck, append to each of them the list of combos for the remaining trips for the second truck, and so on until a truck has only one possible combination left. This uses a reasonable amount of memory, and also is not so slow as one may expect:
I tested it on 18 trips/3 trucks (17153136 combos) and also on 16/4 (63063000 combos). In the latter case it took around 275 seconds on my PC.
(Note: I'm simply returning a tuple of trips for each combo, without splitting it in
ntrucks
subtuples with the truck added. This saves some memory and speeds up things a bit; your fuel consumption calculation will simply need to consider that the firstntrips//ntrucks
elements belong to the first truck, and so on).OPTIMIZATION
Since you want to extract the best combo, why generate them all and then do the calculations? Starting from the code above it would be easy to compute the consumption of each combo once you have it, compare it with the current best and only keep track of the new best, without even maintaining the giant list.
This approach may even allow you to do some forward-check, discarding a combo before it is completely defined, and hence dramatically speeding up the execution.
第一次尝试是使用发电机,而不是立即存储列表中的排列。
这创建了2-3个排列副本:一次创建组合列表一次。(1)
然后,您可以创建另一个列表,其中包含分类元素(2)。
最后,您使用此新列表来创建您的列表。(3)
因此,您可以尝试使用圆形支架使用发电机,然后立即对列表中的元素进行排序:
在这里,您实际上只有一次创建一组,而无需浪费所有的元素中间的空间。
A first try would be to use generators instead of storing the permutations immediately in a list.
This creates 2-3 copies of the permutations: One time by creating the combinations list.(1)
Then you create another list where you have the sorted elements(2).
And finally you use this new list, to create your list.(3)
So instead you can try to use a generator using the round brackets and immediately sort the elements in the lists:
Here you really only once create the set without wasting all the space in the middle.