0

How to generate the different combinations possible for a certain number Example:

m=2 gives:

[1 1;1 2;2 1;2 2]

m=3 gives: [1 1;1 2;1 3;2 1;2 2;2 3;3 1;3 2;3 3] and so on...

using perms([1 2]) generates [1 2;2 1] only

Robert Seifert
  • 25,078
  • 11
  • 68
  • 113
Amira Akra
  • 163
  • 11
  • 1
    These are actually **not** *combinations* in the mathematical sense, as then `[1,2]` and `[2,1]` would be the same. Also they are not *permutations*, that's why `perms` won't work. These are really just *tuples* of the *cartesian product*. This may sound overly exact, but if you search for a solution to this problem, then the correct names will get you a lot further. – knedlsepp Jan 22 '15 at 14:04
  • You can use [this answer](http://stackoverflow.com/a/21895344/2586922) with input `vectors = { 1:m, 1:m }` to generate all tuples ("combinations") – Luis Mendo Jan 22 '15 at 14:37
  • Or equivalently: this answer [this answer](http://stackoverflow.com/a/21895583/2278029) with input `vectors = {1:m 1:m};` `combs = fliplr(combvec(vectors{end:-1:1}).')` to do the same. ;-) – horchler Jan 22 '15 at 20:45
  • possible duplicate of [Generate a matrix containing all combinations of elements taken from n vectors](http://stackoverflow.com/questions/21895335/generate-a-matrix-containing-all-combinations-of-elements-taken-from-n-vectors) – horchler Jan 22 '15 at 20:46
  • @Amira if an answer helped you solved your problem please mark it as accepted. Thanks! – Benoit_11 Jan 25 '15 at 19:05

2 Answers2

2

You can use ndgrid:

m = 3;

[A,B] = ndgrid(1:m);

Here A and B look like this:

A =

     1     1     1
     2     2     2
     3     3     3


B =

     1     2     3
     1     2     3
     1     2     3

So you can concatenate them vertically to get the combinations. Using the colon operator transforms the matrices into column-vectors, i.e. listing all the elements column-wise. Therefore, you could use either

P = sortrows([A(:), B(:)])

or

P = [B(:) A(:)] %// Thanks @knedlsepp :)

to get sorted combinations.

P now looks like this:

P =

 1     1
 1     2
 1     3
 2     1
 2     2
 2     3
 3     1
 3     2
 3     3

Note that your question is highly related to the following, where the goal is to find combinations from 2 vectors.: How to generate all pairs from two vectors in MATLAB using vectorised code?. I suggest you look at it as well to get more ideas.

That being said the question might be a duplicate...anyhow hope that helps.

Community
  • 1
  • 1
Benoit_11
  • 13,905
  • 2
  • 24
  • 35
  • You could even simplify the `ndgrid` line, as `[A, B] = ndgrid(1:m)` is equivalent. – knedlsepp Jan 22 '15 at 13:05
  • 1
    And as we're at it: [B(:) A(:)] could save you the sortrows ;-) – knedlsepp Jan 22 '15 at 13:08
  • is the `ndgrid ` approach applicable to say "4-over-3"? or just the 2d-case? +1 anyway, as it is simpler and faster than mine. – Robert Seifert Jan 22 '15 at 13:08
  • I don't understand sorry; what do you mean by 4 over 3? +1 for you as well :) – Benoit_11 Jan 22 '15 at 13:13
  • 1
    @Benoit_11: As thewaywewalk is also a native german speaker, it's probably the translation problem of "4 über 3", which should translate to "4 choose 3", instead of "4 over 3". – knedlsepp Jan 22 '15 at 13:15
  • thats what I mean knedlsep ;) – Robert Seifert Jan 22 '15 at 13:16
  • 1
    @thewaywewalk: To apply this approach to general `k`-tuples of values `1:n`, I guess this could be generalized using: `Cs = cell(1,k); [Cs{:}] = ndgrid(1:n); tuples = reshape(cat(n+1, Cs{:}),n^k,[]);`, but well, that's more than the OP asked for... By the way: I don't think your approach will work for k=3-tuples of 1:5=n. – knedlsepp Jan 22 '15 at 13:37
  • @knedlsepp I know, that's why I'm asking. – Robert Seifert Jan 22 '15 at 13:52
2

It's a little tricky, as nchoosek can not be used straight out of the box:

n = 3;
X = nchoosek([1:n, n:-1:1],2); 
Y = unique(X,'rows','legacy');

respectively in one line:

Y = unique(nchoosek([1:n, n:-1:1],2),'rows','legacy');
Robert Seifert
  • 25,078
  • 11
  • 68
  • 113
  • Nice! I think there is a typo in the 3rd line; shouln't it be `unique(X,...)` instead of `unique(Z,...)` ? – Benoit_11 Jan 22 '15 at 13:02