我正在尝试生成一个矩阵,它具有[0 0 1 1]的所有唯一组合,我为此编写了以下代码:
v1 = [0 0 1 1];
M1 = unique(perms([0 0 1 1]),'rows');
•这不是理想的,因为perms()将每个向量元素视为唯一的,并且
4! = 4 * 3 * 2 * 1 = 24
组合。
•使用unique()我试图删除所有重复的条目,所以我最终得到组合矩阵M1→
只有[4!/ 2! * (4-2)!] = 6
组合!
现在,当我尝试做一些非常简单的事情,比如:
n = 15;
i = 1;
v1 = [zeros(1,n-i) ones(1,i)];
M = unique(perms(vec_1),'rows');
•而不是得到[15!/ 1! * (15-1)!] = 15
组合,perms()函数试图做
15! = 1.3077e+12
组合并中断。
•你会如何做得更好?提前感谢!
您可以使用nchoosek
来返回应该是1
的索引,我认为在您心中您知道这一定是可能的,因为您正在使用nchoosek
的定义来确定预期的最终排列数!所以我们可以用:
idx = nchoosek( 1:N, k );
其中N是数组v1
中元素的个数,k
是值为1
的元素的个数。然后简单地创建zeros
数组并填充它们。
v1 = [0, 0, 1, 1];
N = numel(v1); % number of elements in array
k = nnz(v1); % number of non-zero elements in array
colidx = nchoosek( 1:N, k ); % column index for ones
rowidx = repmat( 1:size(colidx,1), k, 1 ).'; % row index for ones
M = zeros( size(colidx,1), N ); % create output
M( rowidx(:) + size(M,1) * (colidx(:)-1) ) = 1;
这适用于你的两个例子,而不需要一个巨大的中间矩阵。
旁白:既然您使用这种方法拥有索引,那么您可以创建一个sparse
矩阵,但这是否是个好主意取决于您在此之后要做什么。