【问题标题】:All permutation of number with replacement带替换的所有数字排列
【发布时间】:2014-04-28 06:48:45
【问题描述】:

我想在长度为 4 的向量中生成 0、1、2 的所有可能组合。组合顺序无关紧要,即 11000101,0011,1010 相同。所以我只想选择一个值,即'1100'。能否请您告诉我如何使用 python/perl。

0000
1111
1000
2111
''''
''''

我尝试使用 python 的 itertools.product 但重复了几次。谢谢

【问题讨论】:

  • 您有 R 标签,但在文本中说您正在寻找 python 或 perl 解决方案;你能澄清一下吗?
  • 既然您也标记了 awk,那么您可以使用 awk/shell 解决方案吗?
  • 严格来说是组合而不是排列。

标签: python r perl


【解决方案1】:

这是一个使用 Algorithm::Combinatorics 的 Perl 选项:

use strict;
use warnings;
use Algorithm::Combinatorics qw/combinations_with_repetition/;

print "@$_\n" for combinations_with_repetition( [ 0 .. 2 ], 4 );

输出:

0 0 0 0
0 0 0 1
0 0 0 2
0 0 1 1
0 0 1 2
0 0 2 2
0 1 1 1
0 1 1 2
0 1 2 2
0 2 2 2
1 1 1 1
1 1 1 2
1 1 2 2
1 2 2 2
2 2 2 2

【讨论】:

    【解决方案2】:

    一种方法可以是:

    for i in range(0, 5):
      for j in range (0,5-i):
       print '0'*i+'1'*j+'2'*(4-i-j)+'\n'
    

    【讨论】:

      【解决方案3】:

      在 R 中,您可以执行以下操作:

      x <- 0:2
      out <- unique(t(apply(
         do.call(expand.grid,replicate(4,x,simplify=FALSE)),
         1,
         sort)))
      
            [,1] [,2] [,3] [,4]
       [1,]    0    0    0    0
       [2,]    0    0    0    1
       [3,]    0    0    0    2
       [4,]    0    0    1    1
       [5,]    0    0    1    2
       [6,]    0    0    2    2
       [7,]    0    1    1    1
       [8,]    0    1    1    2
       [9,]    0    1    2    2
      [10,]    0    2    2    2
      [11,]    1    1    1    1
      [12,]    1    1    1    2
      [13,]    1    1    2    2
      [14,]    1    2    2    2
      [15,]    2    2    2    2
      

      【讨论】:

        【解决方案4】:

        这是一个 Python 方法:

        from itertools import combinations
        
        def perm(chars, length):
            s = ''.join([c * length for c in list(chars)])
            combs = combinations(s, length)
            combs = [''.join(comb) for comb in combs]
            combs = list(set(combs))
            combs.sort()
            return combs
        
        for x in perm('012', 4):
            print x
        

        输出:

        0000
        0001
        0002
        0011
        0012
        0022
        0111
        0112
        0122
        0222
        1111
        1112
        1122
        1222
        2222
        

        【讨论】:

        • 非常感谢。您的代码运行良好。
        【解决方案5】:

        您可以使用itertools.product() 并将所有值附加到列表中,然后删除重复项,只要您没有丢失某些值。以下是使用list(set(mylist)) 删除重复项的方法:

        >>> values = []
        >>> values.append(8)
        >>> values.append(9)
        >>> values.append(9)
        >>> values.append(2)
        >>> values.append(8)
        >>> values.append(3)
        >>> values
        [8, 9, 9, 2, 8, 3]
        >>> values = list(set(values))
        >>> values
        [8, 9, 2, 3]
        

        【讨论】:

        • 非常感谢您的宝贵建议和代码。我得到了正确的结果。
        • 记得 +1 和/或接受回答您问题的答案 :)
        【解决方案6】:
        In [91]: for i in itertools.combinations_with_replacement('012', 4): print ''.join(i)
        0000
        0001
        0002
        0011
        0012
        0022
        0111
        0112
        0122
        0222
        1111
        1112
        1122
        1222
        2222
        

        【讨论】:

        • 感谢您的代码。此代码生成所有唯一但重复的组合,因为 0111 与 1110 相同。
        • @FIROZ:很抱歉。我误读了这个问题。查看更新的答案
        【解决方案7】:

        1) 最快。使用gtools库的R解决方案

        gtools::combinations(3, 4, repeats.allowed=TRUE)-1
        

        2) 更快。使用partitions库的R解决方案

        t(apply(partitions::compositions(4,3),2,function(d) rep(c(0,1,2),d)))
        

        3) 较慢。使用prob库的R解决方案

        prob::urnsamples(c(0,1,2), size = 4, replace=TRUE)
        

        【讨论】:

          【解决方案8】:

          使用Math::Combinatorics的Perl解决方案

          use Math::Combinatorics;
          
          use strict;
          use warnings;
          
          my $o = Math::Combinatorics->new(
              count     => 4,
              data      => [0..2],
              frequency => [4,4,4],
          );
          
          while (my @x = $o->next_multiset()) {
              print "@x\n";
          }
          

          输出:

          2 2 2 1
          2 2 2 0
          2 2 2 2
          2 2 1 1
          2 2 1 0
          2 2 0 0
          2 1 1 1
          2 1 1 0
          2 1 0 0
          2 0 0 0
          1 1 1 0
          1 1 1 1
          1 1 0 0
          1 0 0 0
          0 0 0 0
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-10-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-05-02
            • 2014-06-17
            相关资源
            最近更新 更多