combination

13 views (last 30 days)
Niki
Niki on 7 Nov 2011
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
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
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 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

Community Treasure Hunt

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

Start Hunting!