Please help me to improve the following Matlab code to improve execution time.
Actually I want to make a random matrix (size [8,12,10]), and on every row, only have integer values between 1 and 12. I want the random matrix to have the sum of elements which has value (1,2,3,4) per column to equal 2.
The following code will make things more clear, but it is very slow.
Can anyone give me a suggestion??
clc
clear all
jum_kel=8
jum_bag=12
uk_pop=10
for ii=1:uk_pop;
for a=1:jum_kel
krom(a,:,ii)=randperm(jum_bag); %batasan tidak boleh satu kelompok melakukan lebih dari satu aktivitas dalam satu waktu
end
end
for ii=1:uk_pop;
gab1(:,:,ii) = sum(krom(:,:,ii)==1)
gab2(:,:,ii) = sum(krom(:,:,ii)==2)
gab3(:,:,ii) = sum(krom(:,:,ii)==3)
gab4(:,:,ii) = sum(krom(:,:,ii)==4)
end
for jj=1:uk_pop;
gabh1(:,:,jj)=numel(find(gab1(:,:,jj)~=2& gab1(:,:,jj)~=0))
gabh2(:,:,jj)=numel(find(gab2(:,:,jj)~=2& gab2(:,:,jj)~=0))
gabh3(:,:,jj)=numel(find(gab3(:,:,jj)~=2& gab3(:,:,jj)~=0))
gabh4(:,:,jj)=numel(find(gab4(:,:,jj)~=2& gab4(:,:,jj)~=0))
end
for ii=1:uk_pop;
tot(:,:,ii)=gabh1(:,:,ii)+gabh2(:,:,ii)+gabh3(:,:,ii)+gabh4(:,:,ii)
end
for ii=1:uk_pop;
while tot(:,:,ii)~=0;
for a=1:jum_kel
krom(a,:,ii)=randperm(jum_bag); %batasan tidak boleh satu kelompok melakukan lebih dari satu aktivitas dalam satu waktu
end
gabb1 = sum(krom(:,:,ii)==1)
gabb2 = sum(krom(:,:,ii)==2)
gabb3 = sum(krom(:,:,ii)==3)
gabb4 = sum(krom(:,:,ii)==4)
gabbh1=numel(find(gabb1~=2& gabb1~=0));
gabbh2=numel(find(gabb2~=2& gabb2~=0));
gabbh3=numel(find(gabb3~=2& gabb3~=0));
gabbh4=numel(find(gabb4~=2& gabb4~=0));
tot(:,:,ii)=gabbh1+gabbh2+gabbh3+gabbh4;
end
end
Some general suggestions:
what they are indented for. What is
jum_bagfor example? For meuk_popis music style.If you ever have to share your code with a foreigner, you will spend a lot of time
explaining or re-translating. I would like to know for example, what
%batasan tidak bolehmeans. Probably, you describe here that this is only a quickhack but that someone should really check this again, before going into production.
Specific to your code:
gab1withgabh1orgabb1.kromis too similar to the built-in functionkron. In fact, I firstthought that you are computing lots of tensor products.
gab1 .. gab4are probably best combined into an array or into a cell, e.g. youcould use
The advantage is that you can re-write the comparsisons with another loop.
It also helps when computing
gabh1,gabb1andtotlater on.If you further introduce a variable like
highestNumberToCompare, you only have tomake one change, when you certainly find out that its important to check, if the
elements are equal to 5 and 6, too.
Add a semicolon at the end of every command. Having too much output is annoying and
also slow.
The
numel(find(gabb1 ~= 2 & gabb1 ~= 0))is better expressed assum(gabb1(:) ~= 2 & gabb1(:) ~= 0). Afindis not needed because you do not careabout the indices but only about the number of indices, which is equal to the number
of
true‘s.And of course: This code
is really, really slow. In every iteration, you increase the size of the
gab1array, which means that you have to i) allocate more memory, ii) copy the old matrix
and iii) write the new row. This is much faster, if you set the size of the
gab1array in front of the loop:Probably, you should also re-think the size and shape of
gab1. I don’t think, youneed a 3D array here, because
sum()already reduces one dimension (ifkromis3D the output of
sum()is at most 2D).Probably, you can skip the loop at all and use a simple
sum(krom==1, 3)instead.However, in every case you should be really aware of the size and shape of your
results.
Edit inspired by Rody Oldenhuis:
As Rody pointed out, the ‘problem’ with your code is that its highly unlikely (though
not impossible) that you create a matrix which fulfills your constraints by assigning
the numbers randomly. The code below creates a matrix
tempwith the following characteristics:1 .. maxNumberappear either twice per column or not at all.1 .. B, whereBis equal tothe length of a row (i.e. the number of columns).
Finally, the
tempmatrix is used to fill a 3D array calledresult. I hope, you can adapt it to your needs.