permute with exact repeats

1 visualización (últimos 30 días)
mark palmer
mark palmer el 12 de Dic. de 2023
Comentada: Dyuman Joshi el 13 de Dic. de 2023
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

Respuesta aceptada

Voss
Voss el 12 de Dic. de 2023
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 comentarios
mark palmer
mark palmer el 13 de Dic. de 2023
Thanks both that was quick and very helpful!
Voss
Voss el 13 de Dic. de 2023
You're welcome!

Iniciar sesión para comentar.

Más respuestas (1)

Cris LaPierre
Cris LaPierre el 12 de Dic. de 2023
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 comentarios
Adam Danz
Adam Danz el 13 de Dic. de 2023
Editada: Adam Danz el 13 de Dic. de 2023
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 el 13 de Dic. de 2023
Nice approach @Cris LaPierre and @Adam Danz, but OP is working with R2022a, so they won't be able to utilize this.

Iniciar sesión para comentar.

Categorías

Más información sobre Logical en Help Center y File Exchange.

Productos


Versión

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by