【问题标题】:How to generate all possible combinations for the column vectors of a matrix, in MATLAB?如何在MATLAB中为矩阵的列向量生成所有可能的组合?
【发布时间】:2019-11-18 15:57:48
【问题描述】:

如果B=[1; 2]A=[B B B...(n times B)],如何得到C对应A的列向量之间所有可能组合的矩阵。即我想得到同一向量的 n 个副本之间的组合。

例如,对于 n=3:

A =
     1     1     1
     2     2     2

所以,C 可以使用 File Exchange 'allcomb(varargin)' 中的函数获得:

C=allcomb(A(:,1),A(:,2),A(:,3))
C =
     1     1     1
     1     1     2
     1     2     1
     1     2     2
     2     1     1
     2     1     2
     2     2     1
     2     2     2

在我的例子中,n 是可变的。任意n值如何获取C

【问题讨论】:

  • allcomb 不是内置函数,它来自文件交换:allcomb(varargin)。您应该在问题中提及这一点
  • Related。重复?
  • @Luis 我也这么认为,我不认为每个输入向量相同的细微差别使这个问题特别新颖......
  • @Wolfie 我最初标记为欺骗,但后来没有标记,因为这里的真正问题可能是生成输入向量 Bn 副本的逗号分隔列表

标签: matlab matrix combinations


【解决方案1】:

您可以将重复项放在一个单元格中,并使用{:} 语法将所有单元格元素作为allcomb 的输入

n = 3;
B = [1,2];
A = repmat( {B}, n, 1 );
C = allcomb( A{:} ); % allcomb  is FileExchange.
                     % combvec  is a documented alternative.

输出:

C =
 1     1     1
 1     1     2
 1     2     1
 1     2     2
 2     1     1
 2     1     2
 2     2     1
 2     2     2

【讨论】:

  • 感谢您的回答,@Wolfie。它实际上有效,但仅适用于有限的 n 值,因为我正在使用的 B 向量的长度为 100。还有其他解决方案吗?
  • @Ghani 这将生成一个100^n × n 矩阵,因此随着n 的增加,您很快就会耗尽内存。如果这就是问题所在,那么您无能为力。如果可能的话,也许使用uint8 数据类型,但这只会节省内存8
  • @Ghani 如果语法符合您的要求,那么请考虑将此答案标记为已接受...恐怕无法神奇地减少如此大的计算所需的内存,如 Luis 所述
【解决方案2】:

由于每个地方的字母表都相同,因此这实际上是基本转换。 MATLAB 只接受整数基数,但我们可以使用该整数作为字母表的索引B

B=[1; 2];
n = 3;
b = numel(B);

for k = 0:(b^n-1)   % loop over all possible combinations
   C(k+1,:) = dec2base(k, b, n);
end
C = C - '0' + 1;   % convert 0..b-1 (in chars) into 1..b (in ints) for indexing
C = B(C);          % index into alphabet B

结果:

>> C
C =

   1   1   1
   1   1   2
   1   2   1
   1   2   2
   2   1   1
   2   1   2
   2   2   1
   2   2   2

在这种情况下,脚本的最后一行似乎没有太大作用,因为字母表恰好与我们的索引范围相同,但将字母表更改为 B = [7; 14] 将正确导致:

C =

    7    7    7
    7    7   14
    7   14    7
    7   14   14
   14    7    7
   14    7   14
   14   14    7
   14   14   14

【讨论】:

  • 请注意,在 Octave 中,您可以直接将字母指定为向量,从而逐步缩短脚本。
【解决方案3】:

有趣的是,来自 MATLAB File Exchange 的 allcomb 似乎正是您想要的。

allcomb([1; 2],[1; 2], [1; 2])

ans =

     1     1     1
     1     1     2
     1     2     1
     1     2     2
     2     1     1
     2     1     2
     2     2     1
     2     2     2

要对任何n 执行此操作,只需构造矩阵:

>> n = 3;
>> repmat(B, 1, n)

ans =

     1     1     1
     2     2     2

【讨论】:

  • OP 在他们的问题中使用了这个函数,你没有在这个答案中添加任何功能......他们希望避免重复 [1;2] 作为输入,并重复它 n 次- 就像我的回答一样。
  • @mlg556 不幸的是,我有一个长 B 向量(长度(B)=100),我的问题中的示例仅用于说明。在这种情况下,“repmat”似乎只适用于有限的 n 值。
猜你喜欢
  • 2014-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多