【问题标题】:all possible binary matrices with fixed number of 1固定数量为 1 的所有可能的二进制矩阵
【发布时间】:2018-01-09 05:54:01
【问题描述】:

您好,我可以在 matlab 中生成所有可能的二进制矩阵,在每个给定顺序的矩阵中具有固定数量的 1。

例如,所有 4x4 矩阵,每个矩阵中都有两个 1, [1 1 0 0;0 0 0 0;0 0 0 0;0 0 0 0],[1 0 0 0;0 1 0 0;0 0 0 0;0 0 0 0],[1 0 0 0; 0 0 0 0;1 0 0 0;0 0 0 0]

【问题讨论】:

标签: matlab matrix


【解决方案1】:

这是一个矢量化的解决方案:

N = 4; % matrix size
M = 2; % number of ones
ind = nchoosek(1:N^2, M); 
result = zeros(N,N,size(ind,1));
result(bsxfun(@plus, ind, (0:size(ind,1)-1).'*N^2)) = 1;

每个矩阵都是result 的第三维切片:

>> result
result(:,:,1) =
     1     0     0     0
     1     0     0     0
     0     0     0     0
     0     0     0     0
result(:,:,2) =
     1     0     0     0
     0     0     0     0
     1     0     0     0
     0     0     0     0
···
result(:,:,120) =
     0     0     0     0
     0     0     0     0
     0     0     0     1
     0     0     0     1

【讨论】:

    【解决方案2】:

    如果您想创建每个组合,则应该有 (16x15)/2 个组合 (Matsize*Matsize-1)/2),因为您可以在任何地方选择拳头,在任何地方选择第二个,但第一个在哪里并且偏离乘以 2,因为 1-2 与 2-1 相同。请注意,例如,如果您想拥有 3 个“1”,则必须拥有 16x15x14/6(作为 3 个 facotrial)。有一个 MATLAB 函数可以获取每个组合,然后您只需创建每个矩阵,同时使用组合作为索引(在 4x4 矩阵中,您可以将 Matrix(2,1) 寻址为 Matrix(5) )。

    C = combnk(1:16,2); %16 elements and 2 '1'
    Matrizes = zeros(length(C),4,4);
    
    for i=1:size(Matrizes,1)
        Matrizes(i,C(i,:))=1;
    end
    

    肯定有一种方法可以摆脱 for 循环,但由于我不知道这对性能有多重要,所以我选择了简单的方法。

    【讨论】:

      【解决方案3】:

      您可以找到所有长度为 2 的索引子集,然后在该索引中替换 1s。首先使用following code 找到具有指定长度的子集:

      function subsets = get_subset(N, c)
         indices = dec2bin(1:(2 ^ N - 1)) - '0';   % indices of all subsets
         counter = sum(indices, 2);                % number of elements in subsets
         subsets = indices(find(counter == c), :);  % select appropriate subsets
      end
      

      然后,获取所有可能的索引并替换1s:

      n = 10; k = 2;
      A = zeros(n);
      all = cell(1,nchoosek(n,k));
      subsets = get_subset(numel(A), k);
      len = size(subsets,1);
      for i = 1:len
          temp = A;
          temp(find(subsets(i,:) == 1)) = 1;
          all{i} = temp;
      end 
      

      更新: 出于效率考虑,您可以在 matlab 中使用 combnk 作为本机函数,而不是 get_subset

      n = 10; k = 2;
      A = zeros(n);
      all = cell(1,nchoosek(n,k));
      subsets = combnk(numel(A), k);
      len = size(subsets,1);
      for i = 1:len
          temp = A;
          temp(find(subsets(i,:) == 1)) = 1;
          all{i} = temp;
      end
      

      【讨论】:

      • 代码不工作。我认为子集 = combnk(1:numel(A),k)。另一件事是,所有矩阵都是相同的
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-14
      相关资源
      最近更新 更多