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일

1 개 추천

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

Adam Danz
Adam Danz 2023년 12월 13일
편집: Adam Danz 2023년 12월 13일
I had a very similar solution I'll add here as an adapted version of @Voss' answer.
Note the final step that converts the indices back into values from the input vector. I intentionally avoided using 1:3 so that the input values are not confused with index values.
k = [4 5 6];
n = 5;
% generate a matrix M whose rows are all possible
% sets of n elements from k:
m = numel(k);
M = (1+dec2base(0:m^n-1,m)-'0');
% remove rows of M that don't have each element
c = arrayfun(@(x)any(ismember(M,x),2),1:m,'UniformOutput',false);
rm = ~all([c{:}],2);
M(rm,:) = [];
% convert indices to k values
out = k(M)
out = 150×5
4 4 4 5 6 4 4 4 6 5 4 4 5 4 6 4 4 5 5 6 4 4 5 6 4 4 4 5 6 5 4 4 5 6 6 4 4 6 4 5 4 4 6 5 4 4 4 6 5 5
mark palmer
mark palmer 2023년 12월 13일
Thanks both that was quick and very helpful!
Voss
Voss 2023년 12월 13일
You're welcome!

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Cris LaPierre
Cris LaPierre 2023년 12월 12일

2 개 추천

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.

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

제품

릴리스

R2022a

질문:

2023년 12월 12일

댓글:

2023년 12월 13일

Community Treasure Hunt

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

Start Hunting!

Translated by