【问题标题】:optimize all possible combinations of integers优化所有可能的整数组合
【发布时间】:2018-07-04 02:14:09
【问题描述】:

假设我有一个由 5 个整数组成的行向量,其中第一个整数是 int1,第二个是 int2

int1   int2   int3   int4   int5

我想创建一个所有可能组合的列表,假设每个整数都可以在 1 到 99 之间。

一种可能性是编写 5 个嵌套循环:

my list = []

for i in range(1,99):
    for j in range(1,99):
        for k in range(1,99):
            for l in range(1,99):
                for m in range(1,99):
                    my_list.append([[m,l,k,j,i]])

这将非常低效,我们需要 9,509,900,499 次迭代。

有没有更有效的方法将所有可能的组合添加到列表中(即替代 5 个嵌套循环)?

我将用 python 编写代码,但响应不必是特定于 python 的。

【问题讨论】:

  • 如果有 9,509,900,499 种组合,那么您需要将 9,509,900,499 项添加到列表中。
  • 嵌套循环不会使其变慢。嵌套循环被认为是“慢”的,因为迭代的总数很快就会变大。但是您需要执行特定数量的迭代。您可以写出 9,509,900,499 条单独的 append 语句,但速度不会明显提高(忽略加载如此大的程序引起的问题!)。
  • 虽然注意有更简单的方法来编写程序:见docs.python.org/3/library/itertools.html
  • 99% 的情况下,此类问题属于 XY 问题。我建议你试着让我们相信你是剩下的 1%。

标签: python iteration combinatorics


【解决方案1】:

考虑到这一重要评论,有一个简单的解决方案:

是的,我不需要将列表保存在内存中,实际上我可以做到 每个组合都有一些东西并继续前进 - Alejandro Simkievich

你所要做的就是:

import itertools
my_list = itertools.product(xrange(1,99+1), repeat=5)

这在几分之一秒内执行,几乎不占用内存。它实际上并没有创建 99^5 个整数的列表。实际上,它甚至没有创建 99 个整数的列表。这一切都是伪造的。

即使内存中没有列表,my_list 也可以像这样的列表一样迭代:

for int1, int2, int3, int4, int5 in my_list:
    # do_whatever, but this will be executed 9509900499 times, of course
    # try e.g.
    print int1, int2, int3, int4, int5

【讨论】:

  • 这是比 OP 更好的代码;但我注意到它在功能上与他的 5 个嵌套循环相同,只要内部代码正在处理 int 集而不存储它们。
  • @Blorgbeard 与 OP 的代码不同,这个(我的回答中的第一个代码)不需要花费数小时将 70 GB 的数据填充到列表中。除此之外,没有更好的方法,但是没有办法优化 OP 对我们隐藏的核心功能......第二个代码是一个循环,表明它可以像列表一样使用。我已经更新了我的答案以更好地解释(希望如此)
  • 我知道 - 我的意思是您的答案的主要改进可以应用于 5 个嵌套循环 - print 而不是 append。 itertools 或 5 个嵌套循环无关紧要,“只要内部代码正在处理 int 集而不存储它们”。
【解决方案2】:

我刚刚意识到可能有一种方法可以加快并行运行的速度。

假设您有一台具有 99 个内核的机器,您可以在 99 个内核上并行运行四个嵌套循环。在 99 个内核中的每一个内核中,第一个整数都是常数。您将获得 100 倍的效率增益(我猜在实践中会少一点)。

我实际上可以使用 128 核的机器,所以这可能是一个选择。

【讨论】:

  • 当然;与您可以使用具有 11 个内核的机器并行计算 9 个起始数字组的方式相同,例如。不过,我认为这不是特别有见地吗?无论如何,它听起来仍然像 this 的副本
  • 不知道是不是很有见地,但它帮助我解决了问题。无论如何,那些抨击我的问题的人都没有想到它。它可能是重复的,我给你。
  • @AlejandroSimkievich 在 99 个内核上运行,您可以创建 99 个部分列表,是的。最后,如果您想拥有一个大列表,则必须合并它们。还要注意(假设有任何开销),99^5 整数在 64 位机器上需要 70 GB 的 RAM。另请注意,这 70 GB 的内存中绝对没有存储任何信息。所有组合的列表不是信息。那么,目的是什么?
  • @zvone 祝你好运,试图从他身上得到真正的目的。我试过了,但得到的印象是他真的不想说。出于某种原因,它显然需要保密。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多