【问题标题】:All possible combinations with varying lengths不同长度的所有可能组合
【发布时间】:2014-02-24 16:40:27
【问题描述】:

嘿,我有一个数字数组:

[1,2,3,4,5,6,7,8]

我需要找到每个长度不同的数字组合:

[1,2]
[1,3]
[1,4]
.
.
.
[1,2,3,4,5,8]
[1,2,3,4,5,6,7]
[1,2,3,4,5,6,8]
[1,2,3,4,5,6,7,8]

注意:数组中数字的顺序无关紧要。

我想将数组传递给循环内的函数,因此不必担心不同大小的向量。

我在循环中尝试过 perms(),但是它返回的结果太多了。

感谢任何帮助。

【问题讨论】:

  • 您应该预期 2^8 个结果。 perms给你回了多少?
  • 烫发([1,2,3,4,5,6,7,8]);导致 ONE 长度(长度 = 8;)的 40320 个组合

标签: arrays matlab combinations


【解决方案1】:

您可以使用一个技巧来生成带有nchoosek 的所有可变大小组合:引入0 来表示“无数字”(假设您的数字从不为0)。这将产生重复,因此您需要将unique 应用于结果矩阵的行。最后,从每一行中删除零并将结果存储到一个元胞数组中:

v = [1,2,3,4,5,6,7,8]; %// data

n = numel(v);
vz = [zeros(1,n-1) v]; %// add n-1 zeros to represent the absence of a number
r = nchoosek(vz,n); %// generate combinations, one in each row
r = unique(r,'rows'); %// remove duplicate rows
result = arrayfun(@(k) nonzeros(r(k,:)).', 1:size(r,1), 'uni',0); %'// delete 0's

【讨论】:

  • 这是避免循环的好方法!但我认为 OP 想要的是排列而不是组合。
  • @hkf 我不认为这是 OP 想要的排列,是吗?在示例中它们都是按升序排列的
  • 嗯,我想 OP 应该在问题中澄清这一点。
  • 谢谢,效果很好,正是我想要的组合。
【解决方案2】:

MATLAB 有这个函数 NCHOOSEK 用于组合,但这仅适用于固定大小。所以,我们需要通过一个不同大小的循环来运行它。

代码:

v=1:8;
for k = 1:numel(v)-1  
    in1 = nchoosek(v,k+1);
    your_func(in1);
end

【讨论】:

    【解决方案3】:

    由于您需要排列,因此您需要对 nchoosek 的结果运行 perm。矩阵S有组合结果,下面矩阵P有置换结果:

    v = [1,2,3,4,5,6,7,8];
    S ={};
    for ii =1:length(v);
        S{ii} = nchoosek(v,ii);
    end
    P={};
    for kk = 1:length(S)
        data = S{kk};
        for jj = 1:size(data,1)
            P{jj} = perms(data(jj,:));
        end
    end
    

    【讨论】:

      【解决方案4】:

      您要查找的是数组的power set。我对 matlab 了解不多,但 Rosetta Code 声称以下是该算法的 implementation,我觉得它还可以:

      function pset = powerset(theSet)
      
          pset = cell(size(theSet)); %Preallocate memory
      
          %Generate all numbers from 0 to 2^(num elements of the set)-1
          for i = ( 0:(2^numel(theSet))-1 )
      
              %Convert i into binary, convert each digit in binary to a boolean
              %and store that array of booleans
              indicies = logical(bitget( i,(1:numel(theSet)) )); 
      
              %Use the array of booleans to extract the members of the original
              %set, and store the set containing these members in the powerset
              pset(i+1) = {theSet(indicies)};
      
          end
      
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-05-30
        • 2020-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多