How to decrease the time to obtain all possible numerical combinations using the for loop in MATLAB?
Show older comments
Hi all,
I need to decrease the time of possible numerical combinations using for loop. In short, I am analyzing electromyography (EMG) data and doing some simulations with times among some tasks developed by office workers to see which combination creates the greatest variation in muscle. The simulations for 3 and 4 tasks didn't take me long, the problem started when I tried to get combinations for 5 tasks, I left the loop running for more than 2 hours and I still couldn't finish the combinations.
Here is my code:
% Time simulation for six tasks
% Proportion of time
% CWsit | CWstand | NCWsit | NCWstand | NonDeskW | WBreak
% CW = computer work
% NCW = Non-computer work
const = 30; % Here, I set the value 30, because my first task cannot have a value less than that
work_temp = [];
for i = 0:(90-const)
for j = 0:(90-const-i)
for k = 0:(90-const-i-j)
for l = 0:(90-const-i-j-k)
m = 90-const-i-j-k-l;
work_temp = [work_temp;[const+i j k l m]];
end
end
end
end
% note: WBreak has a fixed time of 10% (0.1 in proportion)
% Adding the Wbreak task time vector
work_temp = [work_temp, 10 + zeros(length(work_temp),1)];
Is there any way to make the loop faster?
I know that this loop will result in a huge amount of combinations, so I don't know if it helps much, but the first task cannot have more than 70% of time. (min 30 and max 70). Perhaps the loop can be stopped when get that value.
EDITED: With the help of Walter Roberson (see below) , I was able to obtain the output size, with that value I was able to make the pre-allocation.
% Finding out what matrix size do I need to store my output
const = 30;
[I, J, K, L] = ndgrid(0:90-const);
mask = J <= I & K <= J & L <= K ;
M = 90 - const - I(mask) - J(mask) - K(mask) - L(mask );
% For nested loop to simulate all possible times
const = 30;
work_temp = zeros(length(M),5); % Preallocation (save a lot of time)
c = 0;
tic
for i = 0:(90-const)
for j = 0:(90-const-i)
for k = 0:(90-const-i-j)
for l = 0:(90-const-i-j-k)
m = 90-const-i-j-k-l;
c = c + 1;
work_temp(c,:) = [const+i j k l m];
end
end
end
end
toc
Elapsed time is 0.355317 seconds.
Thanks in advance,
Luiz Augusto
3 Comments
John D'Errico
on 2 Feb 2020
Edited: John D'Errico
on 2 Feb 2020
Hint: preallocation is important. When you grow an array dynemically, it forces MATLAB to constantly increase the size of the array at EVERY iteration. That means MATLAB needs to allocate a new array of size one row larger. Then it needs to copy over the entire array, which is growing at every step.
Perhaps, more important is to ask why you feel you need to create the entire set of combinations. Perhaps there are tools that would allow you not to need to create tham at all. For example, optimization or integer linear programming might come to mind. Far too often, people seem to do things like this for no better reason than they don't know other tools exist that would solve their problem.
Luiz Augusto Brusaca
on 2 Feb 2020
Walter Roberson
on 2 Feb 2020
m will have 635376 entries.
Accepted Answer
More Answers (0)
Categories
Find more on Loops and Conditional Statements in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!