I want to make an array called result, which has dimensions (14,12,10) and has values random[0 2], but it should not contain 0 more than three consecutive times in each row (dimension 2), and the sum of all values in each row must be <= 11.
This is my current approach:
jum_kel = 14;
jum_bag = 12;
uk_pop = 10;
for ii = 1:uk_pop,
libur(:,:,ii) = randint(jum_kel,jum_bag,[0 2]); %#initialis
sum_libur(1,:,ii) = sum(libur(:,:,ii),2); %#sum each row
end
for jj = 1:jum_kel
while sum_libur(1,jj,ii) > 11, %# first constraint : sum each row should be <=11,
libur(jj,:,ii) = randint(1,jum_bag,[0 2])
sum_libur(1,:,ii)= sum(libur(:,:,ii),2);
for kk = 1:jum_bag
if kk>2
o = libur(jj,kk,ii)+libur(jj,kk-1,ii)+libur(jj,kk-2)
while kk>2 && o==0 %# constraint 2: to make matrix will not contain consecutive triplets (0-0-0) in any row.
libur(jj,:,ii) = randint(1,jum_bag,[0 2]);
sum_libur(1,:,ii)= sum(libur(:,:,ii),2);
end
end
end
end
end
but this is extremely slow…Does anyone see a faster method?
As indicated by @ninjagecko, rejecting and recreating is the most obvious (if not the only) way to go here. In that light, I think this’ll do nicely:
Note that
<12equals<=11for integer math (and>3equals>=4), but requires one less check and is thus faster. The variablenewRowis created as a column vector, since such things are better organized in memory and can be checked faster. 3D arrays are generally slower to assign to than 2D matrices, therefore everything is kept 2D until after all operations. The most computationally intense check (~any(diff(find(newRow))>3)) is done last, so that short-circuiting (&&) may render its evaluation unnecessary. Both loops are small and fulfil all conditions to be compiled to machine code by Matlab’s JIT.So this is pretty close to optimized, and will be pretty fast. Unless someone comes up with an entirely different algorithm for this, I believe this is pretty close to the theoretical maximum speed in Matlab. If you need to go faster, you’ll have to switch to C (which will allow optimization of the constraint checks).