如何使用0和1的所有可能组合填充数组?

时间:2014-03-19 01:03:31

标签: arrays matlab dynamic combinations

我有一个算法,0和1的可能组合的数量,可以达到数字2 ^ 39。假设我有n = 2种情况,或者n1 = 2 ^ 2 = 4种组合0和1:00,01,10,11。从那我可以创建一个数组a = zeros(n,n1)并填充列可能的组合?这意味着第一列有00,第二列01,第三列10,最后一行11.我希望这是动态的,这意味着n可以是1,2,3 ...,39,表示数组将是a = 0(n, 2 ^ n)。感谢任何回应!

2 个答案:

答案 0 :(得分:3)

只是为了一般性的理解:为什么你认为你需要一个从0到2³的所有整数的所有组合的数组?该阵列将消耗39×2³⁹/1000⁴≈21TB的RAM ...上次我检查时,只有世界上最先进的超级计算机拥有这样的资源,并且大多数使用这些机器的人都认为生成这样的阵列非常浪费......

无论如何,为了完整性,对于任何N,这是最简单的解决方案:

P = dec2bin(0:(2^N)-1)-'0'

但是,一点建议:dec2bin输出字符数组。如果你想要数值数组,你可以减去字符'0',但是,根据MATLAB的规则,它会给你一个doubles数组:

>> P = dec2bin(0:(2^3)-1)-'0';
>> whos P
  Name      Size            Bytes  Class     Attributes

  P         8x3               192  double                      

如果要最小化内存消耗,请改为生成逻辑阵列:

>> P = dec2bin(0:(2^3)-1)=='1';
>> whos P
  Name      Size            Bytes  Class      Attributes

  P         8x3                24  logical     

如果您还希望加快执行速度,请直接使用标准算法:

%// if you like cryptic one-liners
B1 = rem(floor((0:pow2(N)-1).' * pow2(1-N:0)), 2) == 1;

%// If you like readability
B = false(N,pow2(N));
V = 0:pow2(N)-1;
for ii = 1:N
    B(ii,:) = rem(V,2)==1;
    V = (V-B(ii,:))/2;
end

最后一个(循环)是所有N的所有解决方案中最快的(至少在R2010b和R2013a上),并且它具有最小的峰值记忆(仅为神秘单线的1 / N) 。

所以我会去那个:) 但是,那只是我。

答案 1 :(得分:3)

使用ndgrid作为输出comma-separated list(另请参阅here):

[c{1:N}] = ndgrid(logical([0 1]));
c = cat(N+1,c{N:-1:1});
c = reshape(c,[],N);

示例:N=4给出

c =

     0     0     0     0
     0     0     0     1
     0     0     1     0
     0     0     1     1
     0     1     0     0
     0     1     0     1
     0     1     1     0
     0     1     1     1
     1     0     0     0
     1     0     0     1
     1     0     1     0
     1     0     1     1
     1     1     0     0
     1     1     0     1
     1     1     1     0
     1     1     1     1