使用 MATLAB 生成所有重复组合
Posted
技术标签:
【中文标题】使用 MATLAB 生成所有重复组合【英文标题】:Generating all combinations with repetition using MATLAB 【发布时间】:2015-04-01 19:23:50 【问题描述】:如何使用 MATLAB 创建给定集合(也称为 k-multicombinations 或 multisubsets)的所有 k-combinations with repetitions?
这类似于笛卡尔积,但只有排序不同的两行应该被认为是相同的(例如向量[1,1,2]=~=[1,2,1]
被认为是相同的),因此生成笛卡尔积然后应用@987654323 @ 应该产生相同的结果。
示例:
调用nmultichoosek(1:n,k)
应生成以下矩阵:
nmultichoosek(1:3,3)
ans =
1 1 1
1 1 2
1 1 3
1 2 2
1 2 3
1 3 3
2 2 2
2 2 3
2 3 3
3 3 3
【问题讨论】:
【参考方案1】:我们可以使用wikipedia article 中提到的双射,它将不重复类型n+k-1 choose k
的组合映射到k
-大小为n
的多重组合。我们生成不重复的组合并使用bsxfun(@minus, nchoosek(1:n+k-1,k), 0:k-1);
映射它们。这会产生以下函数:
function combs = nmultichoosek(values, k)
%// Return number of multisubsets or actual multisubsets.
if numel(values)==1
n = values;
combs = nchoosek(n+k-1,k);
else
n = numel(values);
combs = bsxfun(@minus, nchoosek(1:n+k-1,k), 0:k-1);
combs = reshape(values(combs),[],k);
end
【讨论】:
速度快,内存效率高!很好的问答 你真的需要那个reshape
吗? combs = values(combs);
还不够吗?
@LuisMendo:我刚刚做了,所以对于k=1
,它将返回一个列向量。否则可以省略。【参考方案2】:
感谢Hans Hirse 的更正。
蛮力方法:生成所有元组,然后仅保留已排序的元组。不适用于n
或k
的较大值。
values = 1:3; %// data
k = 3; %// data
n = numel(values); %// number of values
combs = values(dec2base(0:n^k-1,n)-'0'+1); %// generate all tuples
combs = combs(all(diff(combs.')>=0, 1),:); %'// keep only those that are sorted
【讨论】:
我可以建议以下更改:combs = combs(all(diff(combs.')>=0, 1),:);
对于k = 2
,diff
的结果是1 x m
向量,这样all
沿第二个轴工作,但是什么您想要的是all
(明确地)沿第一个轴工作,因此将dim
参数设置为1
现在可以使此解决方案也适用于k = 2
。 :-)
@HansHirse 你完全正确。已更新,谢谢!【参考方案3】:
这可能是比以前的帖子更残酷(内存密集型)的方法,但是一个整洁易读的单行:
combs = unique(sort(nchoosek(repmat(values,1,k),k),2),'rows');
【讨论】:
以上是关于使用 MATLAB 生成所有重复组合的主要内容,如果未能解决你的问题,请参考以下文章