combination

Dear I have an matrix
x =
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
I want all combination of changing each variables in first row with other rows for example give me 6 2 8 4 5 and .....

Answers (4)

Image Analyst
Image Analyst on 7 Nov 2011
It seems to me that the brute force way of 5 nested for loops should do it. Each for statement would iterate over all numbers (all rows) in the column. For example (untested)
numberOfRows = size(x, 1);
for row1 = 1 : numberOfRows
for row2 = 1 : numberOfRows
for row3=1 : numberOfRows
for row4 = 1 : numberOfRows
for row5 = 1 : numberOfRows
fprintf('%d %d %d %d %d', x(row1, 1), x(row2, 2), x(row3, 3), x(row4, 4), x(row5, 5));
end
end
end
end
end

2 Comments

Niki
Niki on 7 Nov 2011
this one does not have end
Walter Roberson
Walter Roberson on 7 Nov 2011
It provably has an end after numberofRows^5 operations. On the other hand, that would have been more clear if IA had included \n at the end of the output format string.

Sign in to comment.

Andrei Bobrov
Andrei Bobrov on 7 Nov 2011
c = mat2cell(x,4,[1 1 1 1 1]);
out = cell(1,5);
[out{:}] = ndgrid(c{:});
outd = cell2mat(cellfun(@(x)x(:),out,'un',0));

3 Comments

Niki
Niki on 7 Nov 2011
this one it was an example if I wanted to do it on 5 variables
if it is more what should I do?
for example the example matrix was 5*4
but now I have 10* 4,
I want it works on any matrix that I have Andrei
Sven
Sven on 7 Nov 2011
Cool, I've always been typing "..., 'UniformOuput',false" for my cellfun() calls. You just saved me a bunch of letters.
Niki
Niki on 7 Nov 2011
andrei, I would like to do that for all rows ,
and I would like it be flexible , for example I want to say only I need 100 combination , or more or less,
and I do not know the dimension of my data

Sign in to comment.

Sven
Sven on 7 Nov 2011
I think from your question you want all permutations of the first column and the rest of the columns as a block. I.e., I think in your question where you typed
[6 2 8 4 5]
you actually meant
[6 2 3 4 5].
If so, here is what I would do:
x = [1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20];
inds = 1:4;
[firstInds, secondInds] = meshgrid(inds,inds);
allXcombinations = [x(firstInds(:),1) x(secondInds,2:end)];
disp(allXcombinations)
1 2 3 4 5
1 7 8 9 10
1 12 13 14 15
1 17 18 19 20
6 2 3 4 5
6 7 8 9 10
6 12 13 14 15
6 17 18 19 20
11 2 3 4 5
11 7 8 9 10
11 12 13 14 15
11 17 18 19 20
16 2 3 4 5
16 7 8 9 10
16 12 13 14 15
16 17 18 19 20

9 Comments

Niki
Niki on 7 Nov 2011
yes it is true I want permutations, but lets say this time I have a matrix 10*100 (variables)(in the previous example I had 4*5)
now I want to do the same what should I do?
I want something automatically
and also I want to do for not only the first row , then when all combination of the first row is finished I want to go with second and third and so on.
is it possible to say how many combination I want ?
Sven
Sven on 7 Nov 2011
Ah, sorry for the misunderstanding.
As the size of your matrix increases, it will very quickly become impossible to store all combinations in memory. Instead, you will need to loop over each combination and do your processing inside that loop.
There is a similar concept in this question, admittedly with a different end goal:
http://www.mathworks.com/matlabcentral/answers/19651-generate-sequence
Niki
Niki on 7 Nov 2011
Sven, I saw the work that you did is what I want , just there is some problems, first the dimention of the data is not known,
second I want to have the permutation for all rows
third I would like to have a key to say how many permutation I would like
could you please do me a favor and help me with that?
Sven
Sven on 7 Nov 2011
You mean you would like to limit your output to N number of rows (even if more *possible* answers exist)?
Sven
Sven on 7 Nov 2011
And if you're limiting the output to N number of rows, which do you choose? Any N random solutions?
Niki
Niki on 8 Nov 2011
yes, exactly
Niki
Niki on 8 Nov 2011
No, I would like to put a limitation, but also if I do not put the limitation I want to calculate all possible answer
Sven
Sven on 8 Nov 2011
Yes, but if you *do* put a limitation, how will it work?
For example take your small data set provided. Imagine you put a limitation of "5" results. Which 5 would you choose? Would any random 5 be acceptable?
Niki
Niki on 8 Nov 2011
yes, it does not matter which one, just the first 5 for example

Sign in to comment.

Sven
Sven on 9 Nov 2011
Mohammad, try this for a solution. It is a loop that iterates along the columns of x, picking the next available x(row,col). When it reaches the end of the columns, it prints out to the screen the "solution" it just found.
This avoids memory issues because it doesn't store every combination of results, it just prints them. It should work fine on any size input set you provide. If you wanted to do some processing on each solution, you can embed your processing within the loop. Here it is:
First set up "x" and "solutionLimit". You can set solutionLimit to Inf if you want all solutions printed.
x = [1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20];
solutionLimit = 50;
Now for the function itself:
[nRows,nCols] = size(x);
rowSet = zeros(1,nCols); % Which row of x are we up to at each col?
thisSol = zeros(1,nCols); % The running list of our current solution
colNo = 1; solutionCount = 0; % Initialise
while solutionCount < solutionLimit
rowSet(colNo) = rowSet(colNo)+1; % Get the next free number
if rowSet(colNo)>nRows % Is this col out of numbers?
if all(rowSet>=nRows), break; end % Are we ALL finished?
rowSet(colNo) = 0; colNo = colNo - 1; continue;
end
thisSol(colNo) = x(rowSet(colNo), colNo); % Append to our solution
% If we're at the last column, print the solution. Otherwise move on.
if colNo==nCols
solutionCount = solutionCount+1;
fprintf('#%d: %s\n',solutionCount, sprintf('%d ',thisSol))
else
colNo = colNo + 1;
end
end

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Asked:

on 7 Nov 2011

Community Treasure Hunt

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

Start Hunting!