permn  permutations with repetition
Using two input variables V and N, M = permn(V,N) returns all
permutations of N elements taken from the vector V, with repetitions.
V can be any type of array (numbers, cells etc.) and M will be of the
same type as V. If V is empty or N is 0, M will be empty. M has the
size numel(V).^NbyN.
When only a subset of these permutations is needed, you can call permn
with 3 input variables: M = permn(V,N,K) returns only the Kths
permutations. The output is the same as M = permn(V,N) ; M = M(K,:),
but it avoids memory issues that may occur when there are too many
combinations. This is particulary useful when you only need a few
permutations at a given time. If V or K is empty, or N is zero, M will
be empty. M has the size numel(K)byN.
[M, I] = permn(...) also returns an index matrix I so that M = V(I).
Examples:
M = permn([1 2 3],2) % returns the 9by2 matrix:
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
M = permn([99 7],4) % returns the 16by4 matrix:
99 99 99 99
99 99 99 7
99 99 7 99
99 99 7 7
...
7 7 7 99
7 7 7 7
M = permn({'hello!' 1:3},2) % returns the 4by2 cell array
'hello!' 'hello!'
'hello!' [1x3 double]
[1x3 double] 'hello!'
[1x3 double] [1x3 double]
V = 11:15, N = 3, K = [2 124 21 99]
M = permn(V, N, K) % returns the 4by3 matrix:
% 11 11 12
% 15 15 14
% 11 15 11
% 14 15 14
% which are the 2nd, 124th, 21st and 99th permutations
% Check with permn using two inputs
M2 = permn(V,N) ; isequal(M2(K,:),M)
% Note that M2 is a 125by3 matrix
% permn can be used generate a binary table, as in
B = permn([0 1],5)
NB Matrix sizes increases exponentially at rate (n^N)*N.
See also perms, nchoosek
allcomb, permpos on the File Exchange
Jos (10584) (2020). permn (https://www.mathworks.com/matlabcentral/fileexchange/7147permn), MATLAB Central File Exchange. Retrieved .
6.2.0.0  fixed coding style warnings 

6.1.0.0  spelling corrections 

6.1.0.0  Incorporated the functionality of permnsub, allowing for returning a subset rather than all permutations as well. 

5.1.0.0  Renamed file into PERMN, fixed small bug, extended help section 

1.3.0.0  Reference to COMBNSUB for large combinatorial problems. 

1.2.0.0  corrected to give column vector output for N=1. (error pointed out by Wilson via email). 

1.1.0.0  modified slightly based on suggestions by Jan Simon (thanks!) 

1.0.0.0  fast algorithm 

arggg updated with older version ... 

new (very fast) algorithm 

new faster algorithm 
Inspired: N_PERMUTE_K, VChooseKRO, de Bruijn sequence generator, Kautz sequence generator, permnsub(V,N, IX)
Create scripts with code, output, and formatted text in a single executable document.
Thank you :)
Thanks, this was helpful and was easy to follow!
Great! Thank you.
Absolutely fantastic! Thank you
A top submission on FEX, that should be in everyone's collection of handy functions.
Very well written, efficient, neat code with comprehensive help. Does exactly what it says on the tin.
Time saver! Thanks! :D :D
I have Already wasted hours trying to code it but glad I found your code. It saved me much time! Thank you very much :)
That saved me hours of trying to code that function, thanks!
@Cameron Download the function, unzip in a folder and add that folder to your path. See the documentation
I'm new to MatLab. Can someone tell me how I can call this in my own MatLab program.
A very quick algorithm to find the permutations. A great work
or as a full function as follows;
function result=seqrep(V,N)
l=length(V);
a=zeros(l^N,N);
for i=1:N
a(:,i)=reshape(reshape(repmat((1:l),1,l^(N1)),l^i,l^(Ni))',l^N,1);
end
result=V(a);
i guess this can be done using only 1 for loop as shown below;
for i=1:n
a(:,i)=reshape(reshape(repmat((1:l),1,l^(n1)),l^i,l^(ni))',l^n,1);
end
where n= number of elements (as N here) and
l= length of V
Please help me to solve it
A=[30 30 30 30 30 30 60 60 60 60 60 60 60 60 30 30 30 30 30 30];
[c,b] = hist(A,unique(A));
N= length(A);
x = permn(b,N); %function permn
I have matrix A. i want to sort x. i need c(1,1) no of angle of 30. and c(1,2) no of angle of 60. means i need 12 nos of 30 and 8 nos of 60 in every permutations. How can i do it...please help me. Just like perm command works. but it's limited to 10. i need 20.
I also have another program but it's only works with 0 and 1.
A=[1 1 0 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1];
n2 = numel(A);
b2 = nnz(A);
M2 = 0:ones(1,n2)*pow2(n21:1:0)';
z2 = rem(floor(M2(:)*pow2(1n2:0)),2);
out = z2(sum(z2,2) == b2,:);
On second thoughts, I change the name as well. Thanks!
I know, Stephen. I decided to keep the original name for backward compatibility. Note that this function is more than 10 years old and still regularly downloaded.
I will update the description though!
This submission is misnamed:
* If the order doesn't matter, it is a Combination.
* If the order does matter it is a Permutation.
It is clear from the example that this submission generates what is sometimes called "permutations with repetitions":
http://en.wikipedia.org/wiki/Permutation
If this submission truly calculated the combinations then the sets {0,0,1}, {0,1,0}, and {1,0,0} are all equivalent, and would not all appear in the output shown in the example.
http://en.wikipedia.org/wiki/Combination
http://mathworld.wolfram.com/Combination.html
or for a simpler introduction:
https://www.mathsisfun.com/combinatorics/combinationspermutations.html
saved me sometime!
Thank you very much!
verry useful, thank you
Repetitive combination, great!
@Marc, thanks for your interest and suggestions for improvement. Yet, for code compatibility (and fairness) you need to implement to inverse order step as well :)
Nice code, thanks! Just for fun, slight to medium speed improvement (sorry my k = your N):
%instead of:
%[Y{k:1:1}] = ndgrid(X) ;
%Y = reshape(cat(k+1,Y{:}),[],k) ;
%fill Y directly:
nX = numel(X);
Y(nX^k, k) = X(1); % Initialize to give shape and data type.
s(1:k1) = {ones(1, nX)};
for i = 1:k
Y( ((i1)*nX^k + 1) : (i*nX^k) ) = X(s{1:i1}, :, s{i:k1});
X = permute(X, [1:i1, i+1, i]);
end
% This has inverse order for the combinations as you had, easy to change.
@ Talaria, this is impossible as it would require a memory of (at least) 150*(2^150) bits which is about 2700000000000000000000000000000000 Terabyte ...
However, it is unlikely that you need all those combinations at once; perhaps you can think of another approach to your problem, for instance, by drawing a few random combinations at a time?
works great, but is there a way to beat the limitation? for example i want to be able to return the following:
M = COMBN([0 1],150)
is this possible?
The core of this function is a lovely little computational gem. Thank you.
Excellent and fast!
Excellent, just what I needed. Thanks!
Does anyone have an idea on how to create a function like "combn" but where the generated matrix contains only monotone rows? I could do it manually by removing nonmonotone rows after having built the matrix, but when the size of the matrix becomes large i got out of memory error. Any idea?
Can't find a better suited H1line. Neat help, simple example, history (maybe more details on the dates...) and past algorithms too.
I don't use combinatorics very much but I always wonder why matlab doesn't cover it esplicitly. A must have.
Oleg
Nice and comapct program! H1line, help, history, comments in the code, efficient. Thanks!
But can be made still a little bit faster:
X = repmat({X},1,N) ;
[X{1:N}] = ndgrid(X{:}) ;
X = fliplr(reshape(cat(N+1,X{:}),[],N)) ;
1. If X is filled in reverse order with [X{N:1:1}], FLIPLR can be omitted => 25% faster for COMBN(1:10, 5) (see my comment for ALLCOMB)
2. Inside NDGRID the same operations are performed for each input, but all inputs are equal. Inlining and simplyfying NDGRID leads to (REPMAT can be omitted then):
C = cell(1, N);
X = X(:);
L = length(X);
s(1:N  1) = L;
X = reshape(X(:, ones(1, prod(s))), [L, s]);
C{N} = X;
for iC = 2:N
C{N  iC + 1} = permute(X, [2:iC, 1, iC + 1:N]);
end
X = reshape(cat(N+1, C{:}), [], N);
=> 4050% faster.
To my surprise it is *slower* to create the output array at once and insert the permuted subarrays directly.
Thanks!
any idea of how to get the combinations without repetition of previous combinations, and without reusing the elements in a a selection?
Exactly what I was looking for!
Thanks a million!
Does the job...
Roger Stafford pointed out that, due to the IEEE 754 standard, the floor of a floating point (as used in COMBN's algorithm) may lead to faulty results for very specific inputs.
The update incorporates his excellent solution to this potential problem. Thanks Roger!
The update (COMBN version 3.2) should be up soon ...
It is very useful, thanks !
Fast and (almost) exactly what I needed!
... I only need those combinations which sum to (say) one. I can, of course, first create all combinations with this program and then find(m*ones(N,1)==1). Yet I bounce very quickly against maximum variable size for Matlab. Any Suggestions?
Thanks a lot
I am very surprised this is not a build in function. You saved my day thanks a lot!
Thanks! Exactly what I needed.
What I needed!
Very fast! Very helpful to solve my actual problem.
Great tool. Easy to use.
Easy to use, fast, and suitable for incorporating into other programs. Good documentation well organized. It really helped me solve some problems.
Jamie, use COMBN(UNIQUE(V),N)
Does what it says, but there really should be an option to treat elements as nonunique.