【问题标题】:how to generate all possible combinations of a 14x10 matrix containing only 1's and 0's如何生成仅包含 1 和 0 的 14x10 矩阵的所有可能组合
【发布时间】:2011-03-18 19:55:24
【问题描述】:

我正在解决一个问题,一种解决方案需要输入每个可能由 1 和 0 组成的 14x10 矩阵...我如何生成这些以便我可以将每个可能的 14x10 矩阵输入另一个功能?谢谢!

3 月 21 日添加:看来我的帖子措辞不当。对不起。我正在尝试做的是针对几种情况优化 10 个不同生产单元的输出(给定不同的速度和停机时间)。我的目标是设置停机时间块,以最大限度地减少日常生产中的差异。给出了每个单元允许的停机时间和频率。我目前正在尝试评估一个三周的周期,这意味着每三周每个生产单元都会在给定的小时内停机。我要求计算机根据生产线每 3 周仅停机一次且每日产量差异尽可能小的约束来确定设备的拆卸顺序。我的第一种方法是使用 Excel(正如我在上面试图描述的那样),但它不起作用(没有惊喜)......其中 1- 运行,0- 关闭以及何时将这些相加以计算产量。从设定的最大日产量中减去计算出的产量。然后,将这些差异从周一到周二、周二到周三等进行了为期三周的时间框架进行比较,并使用求解器将其最小化。我的下一个方法是编写一个 Matlab 代码,其中输入是一个容差(设置允许的日常变化)。是否有已经这样做的程序或最简单的方法?看起来很简单,但我仍在考虑不同的方法来解决这个问题。任何见解将不胜感激。

【问题讨论】:

  • 您当然意识到有 2**140 个这样的矩阵(大约 1.4e42)?
  • ...如果您每秒可以处理十亿个这样的矩阵,那么处理所有这些矩阵只需要 宇宙当前年龄的 5000 万倍吗? ?
  • @Tiffany 而不是蛮力方法,您可能会考虑使用诸如蒙特卡罗采样或最小化例程之类的方法,具体取决于具体应用。
  • 9 个答案,其中大多数根本不是答案,它们是 cmets。请停止发布 cmets 作为答案,以期获得错位的选票...
  • @Glenn 正确的“答案”基本上是这无法完成……OP 确实想做其他事情,但对具体细节不清楚。

标签: python arrays matlab matrix


【解决方案1】:

实际的实现很大程度上取决于你想如何表示矩阵……但假设矩阵可以用一个 14 * 10 = 140 的元素列表表示:

from itertools import product
for matrix in product([0, 1], repeat=140):
    # ... do stuff with the matrix ...

当然,正如其他发帖者所指出的,这可能不是您想要做的……但如果这确实是您想要做的,那是最好的代码(根据您的要求)。

【讨论】:

  • 抱歉,我不确定有什么不清楚的地方。表示矩阵的一种方法是列表(例如,矩阵中的元素 (x, y) 对应于列表中的元素 x * width + y),我提供的代码将生成每 140 个元素的列表(所以每 14x10 矩阵),其中每个元素是01
  • 仍然完全不现实,但我很高兴有人终于发布了答案。
  • 太糟糕了,一旦算法完成,地球就不会存在了:)
  • @josh.trow:哦,是的,完全不现实。但希望itertools.product 的使用会有所启发。
  • @Michael McGowan: 派对大便:)
【解决方案2】:

14*10 生成每个可能的 1 和 0 矩阵将生成 2**140 矩阵。我不相信你会有足够的生命来做这件事。我不知道,在你完成之前,太阳是否还会照耀。这就是为什么不可能生成所有这些矩阵的原因。您必须寻找其他解决方案,这看起来很暴力。

【讨论】:

  • 这是评论,不是答案。
【解决方案3】:

这绝对不可能!可能的矩阵数为 2140,大约为 1.4e42。但是,请考虑以下...

  • 如果您要随机生成两个 14×10 矩阵,它们相同的几率是 1.4e42 中的 1。
  • 如果您要生成 10 亿个独特的 14×10 矩阵,那么您生成的下一个与其中一个相同的几率仍然非常小:1.4e33 中的 1 个。
  • default random number stream in MATLAB 使用周期为 219936-1 的 Mersenne twister 算法。因此,随机数生成器不应在本世纪的任何时候开始重复。

你的方法应该是这样的:

  • 找一台没人想再用的电脑。
  • 为其提供尽可能多的存储空间以保存您的结果。
  • 在其上安装 MATLAB 并启动它。
  • 像这样开始随机计算矩阵:

    while true
      newMatrix = randi([0 1],14,10);
      %# Process the matrix and output your results to disk
    end
    
  • 走开

由于有如此多的组合,您不必将newMatrix 与之前的任何矩阵进行比较,因为重复发生之前的时间长度可能是天文数字。您的处理更有可能首先由于其他原因而停止,例如(按可能发生的顺序):

  • 存储结果的磁盘空间不足。
  • 停电了。
  • 您的计算机发生了致命的硬件故障。
  • 你去世了。
  • 地球消逝了。
  • 宇宙慢慢消亡heat death

注意:虽然我在上面的答案中注入了一些幽默感,但我认为我已经说明了一个有用的替代方案。如果您只是想对可能的组合中的一小部分 子集 进行抽样(由于组合的数量庞大,甚至 10 亿个都可以被认为是“小”),那么您不必经历额外的保存您已经处理过的所有矩阵并将新的矩阵与它进行比较以确保您没有重复矩阵的耗时和内存步骤。由于重复组合的几率非常低,您可以安全地这样做:

for iLoop = 1:whateverBigNumberYouWant
  newMatrix = randi([0 1],14,10);  %# Generate a new matrix
  %# Process the matrix and save your results
end

【讨论】:

  • 有快速热死这种东西吗? :)
【解决方案4】:

确定你想要所有可能的 14x10 矩阵吗?每个矩阵有 140 个元素,每个元素可以打开或关闭。因此有2^140 可能的矩阵。我建议你重新考虑你真正想要什么。

编辑:我注意到你在评论中提到你试图最小化一些东西。有一个名为optimization 的完整数学领域致力于做这类事情。存在此字段的原因是因为通常不可能在任何类似合理的时间内详尽地检查每个解决方案。

【讨论】:

    【解决方案5】:

    试试这个:

    import numpy
    for i in xrange(int(1e9)): a = numpy.random.random_integers(0,1,(14,10))
    

    (这比您需要的要小得多)应该足以让您相信这是不可行的。它还向您展示了如何计算一个或几个这样的随机矩阵,即使达到一百万也非常快)。

    编辑:更改为 xrange 以“提高速度和内存要求”:)

    【讨论】:

    • 这里最好使用xrange(int(1e9));在 Py2 中,range(int(1e9)) 将预先分配一个十亿元素的列表,这是不必要的
    【解决方案6】:

    您不必对此进行迭代:

    def everyPossibleMatrix(x,y):
        N=x*y
        for i in range(2**N):
            b="{:0{}b}".format(i,N)
            yield '\n'.join(b[j*x:(j+1)*x] for j in range(y))
    

    【讨论】:

    • 那么...两个 for 循环如何不迭代?
    • +1 非常棒地使用了新的string.format 选项……但是 在 Py2 中,range 会预先分配给定大小的列表,这会很快耗尽你的内存。 xrange 会更好,因为它返回一个迭代器。当然,在 Py3 中这不是问题……
    【解决方案7】:

    根据您希望使用生成的矩阵完成的任务,您最好生成一个随机样本并运行多个模拟。比如:

    matrix_samples = []
    # generate 10 matrices
    for i in range(10):
        sample = numpy.random.binomial(1, .5, 14*10)
        sample.shape = (14, 10)
        matrix_samples.append(sample)
    

    您可以多次执行此操作,以查看模拟结果的差异。当然,您也可以修改代码以确保样本集中没有重复,这同样取决于您要完成的工作。

    【讨论】:

      【解决方案8】:

      您是说您有一个包含 140 个单元格且每个值可以是 1 或 0 的表格,并且您想要生成所有可能的输出?如果是这样,您将有 2^140 种可能的组合......这是一个相当大的数字。

      【讨论】:

      • 是的...我正在尝试最小化需要将 10x14 表中的每个单元格更改为 1 或 0 的内容。
      • @Tiffany:“将 10x14 表中的每个单元格更改为 1 或 0”与生成每个可能的 10x14 矩阵不同。你真的需要更多地解释你的问题。
      • 你原来的问题是什么?您是否正在尝试解决一些现实世界的问题?
      【解决方案9】:

      我建议考虑一种对所有可能组合的重要子集进行采样的方案,而不是应用蛮力方法,而不是仅仅暗示这是不可行的。正如您的答复之一所建议的那样,您正在最小化。有一些数值技术可以做到这一点,例如模拟退火、蒙特卡罗采样以及传统的最小化算法。您可能想了解一个是否适合您的情况。

      【讨论】:

      • 我“有点”同意你的回答,但显然 OP 应该提供更多细节,否则 OP 的问题只不过是个玩笑。谢谢
      【解决方案10】:

      其实我一开始就比较悲观,但是考虑一下:

      from math import log, e
      
      def timeInYears(totalOpsNeeded=2**140, currentOpsPerSecond=10**9, doublingPeriodInYears=1.5):
          secondsPerYear = 365.25 * 24 * 60 * 60
          doublingPeriodInSeconds = doublingPeriodInYears * secondsPerYear
          k = log(2,e) / doublingPeriodInSeconds  # time-proportionality constant
          timeInSeconds = log(1 + k*totalOpsNeeded/currentOpsPerSecond, e) / k
          return timeInSeconds / secondsPerYear
      

      如果我们假设计算机处理能力继续每 18 个月翻一番,并且您目前每秒可以进行 10 亿次组合(乐观,但为了争论)并且您从今天开始,您的计算将在 4 月左右完成2137 年 29 日。

      【讨论】:

      • 当然现在你必须弄清楚如何存储它。保存所有矩阵大约需要 24 兆字节 :)
      【解决方案11】:

      这是开始使用 Matlab 的一种有效方法:

      首先生成所有 1024 个长度为 10 的可能行,其中仅包含 0 和 1:

      dec2bin(0:2^10-1)
      

      现在您有了所有可能的行,您可以根据需要从中采样。例如通过多次调用以下行:

      randperm(1024,14)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-27
        相关资源
        最近更新 更多