permute with exact repeats

1 次查看(过去 30 天)
I'm trying to permute a comprehensive list of 3 elements, say [1 2 3]
over a 5-size array with at least 1 element included from the 3 element array. (I'd like it the result be general, so the variables might be 3 over 6, 4 over 7, etc.) Obviously I can do this by brute force but I'd prefer a more elegant solution.
The result would be
1 1 1 2 3
1 1 1 3 2
1 1 2 1 3
1 1 2 3 1
1 1 3 1 2
1 1 3 2 1
1 1 3 2 2
1 1 3 3 2
1 2 1 1 3
1 2 1 2 3
...
3 3 3 2 1

采纳的回答

Voss
Voss 2023-12-12
Here's one way:
x = [1 2 3];
n = 5;
% generate a matrix M whose rows are all possible
% sets of n elements from x:
m = numel(x);
M = x(1+dec2base(0:m^n-1,m)-'0');
% remove rows of M that don't have each element
% of x at least once:
for ii = 1:m
M(~any(M == x(ii),2),:) = [];
end
disp(M)
1 1 1 2 3 1 1 1 3 2 1 1 2 1 3 1 1 2 2 3 1 1 2 3 1 1 1 2 3 2 1 1 2 3 3 1 1 3 1 2 1 1 3 2 1 1 1 3 2 2 1 1 3 2 3 1 1 3 3 2 1 2 1 1 3 1 2 1 2 3 1 2 1 3 1 1 2 1 3 2 1 2 1 3 3 1 2 2 1 3 1 2 2 2 3 1 2 2 3 1 1 2 2 3 2 1 2 2 3 3 1 2 3 1 1 1 2 3 1 2 1 2 3 1 3 1 2 3 2 1 1 2 3 2 2 1 2 3 2 3 1 2 3 3 1 1 2 3 3 2 1 2 3 3 3 1 3 1 1 2 1 3 1 2 1 1 3 1 2 2 1 3 1 2 3 1 3 1 3 2 1 3 2 1 1 1 3 2 1 2 1 3 2 1 3 1 3 2 2 1 1 3 2 2 2 1 3 2 2 3 1 3 2 3 1 1 3 2 3 2 1 3 2 3 3 1 3 3 1 2 1 3 3 2 1 1 3 3 2 2 1 3 3 2 3 1 3 3 3 2 2 1 1 1 3 2 1 1 2 3 2 1 1 3 1 2 1 1 3 2 2 1 1 3 3 2 1 2 1 3 2 1 2 2 3 2 1 2 3 1 2 1 2 3 2 2 1 2 3 3 2 1 3 1 1 2 1 3 1 2 2 1 3 1 3 2 1 3 2 1 2 1 3 2 2 2 1 3 2 3 2 1 3 3 1 2 1 3 3 2 2 1 3 3 3 2 2 1 1 3 2 2 1 2 3 2 2 1 3 1 2 2 1 3 2 2 2 1 3 3 2 2 2 1 3 2 2 2 3 1 2 2 3 1 1 2 2 3 1 2 2 2 3 1 3 2 2 3 2 1 2 2 3 3 1 2 3 1 1 1 2 3 1 1 2 2 3 1 1 3 2 3 1 2 1 2 3 1 2 2 2 3 1 2 3 2 3 1 3 1 2 3 1 3 2 2 3 1 3 3 2 3 2 1 1 2 3 2 1 2 2 3 2 1 3 2 3 2 2 1 2 3 2 3 1 2 3 3 1 1 2 3 3 1 2 2 3 3 1 3 2 3 3 2 1 2 3 3 3 1 3 1 1 1 2 3 1 1 2 1 3 1 1 2 2 3 1 1 2 3 3 1 1 3 2 3 1 2 1 1 3 1 2 1 2 3 1 2 1 3 3 1 2 2 1 3 1 2 2 2 3 1 2 2 3 3 1 2 3 1 3 1 2 3 2 3 1 2 3 3 3 1 3 1 2 3 1 3 2 1 3 1 3 2 2 3 1 3 2 3 3 1 3 3 2 3 2 1 1 1 3 2 1 1 2 3 2 1 1 3 3 2 1 2 1 3 2 1 2 2 3 2 1 2 3 3 2 1 3 1 3 2 1 3 2 3 2 1 3 3 3 2 2 1 1 3 2 2 1 2 3 2 2 1 3 3 2 2 2 1 3 2 2 3 1 3 2 3 1 1 3 2 3 1 2 3 2 3 1 3 3 2 3 2 1 3 2 3 3 1 3 3 1 1 2 3 3 1 2 1 3 3 1 2 2 3 3 1 2 3 3 3 1 3 2 3 3 2 1 1 3 3 2 1 2 3 3 2 1 3 3 3 2 2 1 3 3 2 3 1 3 3 3 1 2 3 3 3 2 1
  3 个评论
mark palmer
mark palmer 2023-12-13
Thanks both that was quick and very helpful!

请先登录,再进行评论。

更多回答(1 个)

Cris LaPierre
Cris LaPierre 2023-12-12
I think this does what you are looking for.
v = 1:3;
% create all 5-digit possible combinations
T = table2array(combinations(v,v,v,v,v));
% Extract only those that contain a 3 numbers
idx = any(T==1,2) & any(T==2,2) & any(T==3,2);
T = T(idx,:)
T = 150×5
1 1 1 2 3 1 1 1 3 2 1 1 2 1 3 1 1 2 2 3 1 1 2 3 1 1 1 2 3 2 1 1 2 3 3 1 1 3 1 2 1 1 3 2 1 1 1 3 2 2
  2 个评论
Adam Danz
Adam Danz 2023-12-13
编辑:Adam Danz 2023-12-13
Great idea to use combinations (R2023a and later).
I fiddled with your solution a bit to make it flexibly receive any number of combinations.
v = 1:3;
n = 5;
% create all 5-digit possible combinations
in = repelem({v},1,n);
A = table2array(combinations(in{:}));
% Extract only those that contain a 3 numbers
c = arrayfun(@(x)any(ismember(A,x),2),v,'UniformOutput',false);
rm = ~all([c{:}],2);
A(rm,:) = []
A = 150×5
1 1 1 2 3 1 1 1 3 2 1 1 2 1 3 1 1 2 2 3 1 1 2 3 1 1 1 2 3 2 1 1 2 3 3 1 1 3 1 2 1 1 3 2 1 1 1 3 2 2
Dyuman Joshi
Dyuman Joshi 2023-12-13
Nice approach @Cris LaPierre and @Adam Danz, but OP is working with R2022a, so they won't be able to utilize this.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Matrices and Arrays 的更多信息

产品


版本

R2022a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by