我想知道是否有办法为2个向量生成所有可能的排列。我知道我可以使用烫发,但这只适用于一个载体。
我想要的是输入矢量[1 2 3] 并且会离开
V1 = [] V2 = [1 2 3]
V1 = [1 2 3] V2 = []
V1 = [1] V2 = [2 3]
V1 = [2] V2 = [1 3]
...
我也可以将所有这些排列存储在单元格数组中,因为它们都有不同的长度,因此矩阵不起作用。
答案 0 :(得分:4)
这是你想要的吗?
output = {};
v = [1 2 3]; % input
N = length(v);
for k=1:2^N
m = logical( bitget(k, 1:N) ); % mask selecting elements of v1
v1 = v(m);
v2 = v(~m);
output{end+1} = {v1, v2};
end
答案 1 :(得分:1)
在几乎一行中,功劳应该转到seb。
v = [1 2 3 4];
N = numel(v);
out = cellfun(@(x) {v(x) v(~x)}, mat2cell( logical( bsxfun(@bitget,(1:2^N)', (1:N)) ) ,ones(1,2^N),N) , 'uni', 0)
我的老答案,笨拙,但有效:
A = arrayfun(@(x) nchoosek(V,x), 1:numel(V), 'uni',0);
B = cellfun(@(x) mat2cell(x,ones(1,size(x,1)),size(x,2)),A,'uni',0);
V1 = vertcat({[]},B{:});
V2 = cellfun(@(x) setdiff(V,x), V1, 'uni',0);
给出:
>> celldisp(V1)
V1{1} =
[]
V1{2} =
1
V1{3} =
2
V1{4} =
3
V1{5} =
1 2
V1{6} =
1 3
V1{7} =
2 3
V1{8} =
1 2 3
和V2
正好相反。
答案 2 :(得分:0)
尝试以下解决方案:
a=num2cell(1:3);
output1=cellfun(@(x) nchoosek(1:3,x),a,'UniformOutput',false);
output_reverse=cellfun(@(x) nchoosek(3:-1:1,x),a(2:3),'UniformOutput',false);
对于1,2,3
的序列,输出如下:
output1{1}=
1
2
3
output1{2}=
1 2
1 3
2 3
output1{3}=
1 2 3
仅在需要反向组合时才执行output_reverse
行。希望这是你正在寻找的。 p>
答案 3 :(得分:0)
对所有可能的分区使用循环。对于每个除法,计算一个掩码(逻辑索引),该掩码告诉哪些元素转到V1
,哪些转到V2
。以下假定顺序并不重要,即[1],[2 3]
与[1], [3 2]
的分区相同。
vector = [1 2 3]; %// example data
N = numel(vector); %// number of elements
NN = 2^N; %// number of results
V1 = cell(1,NN); %// intiallize
V2 = cell(1,NN); %// intiallize
for n = 0:NN-1;
mask = logical(dec2bin(n,N)-'0'); %// logical index for values in V1
V1{n+1} = vector(mask);
V2{n+1} = vector(~mask);
end