Speeding up Binary Matricies Generation with given conditions
1 vue (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Eric Noname
le 22 Jan 2015
Commenté : Roger Stafford
le 22 Jan 2015
Need help speeding up my code that produces 3x3 Binary Matrix only if it meets all the fixed row and column sums. It currently times out a lot before it generates the matrix and I need to get it faster to modify it for a 5x5. Also want to mention that there is probably a few things wrong in my code, and that is because I am a beginner a small idea on how I am forcing it to work.
rows = 3;
columns = 3;
C1=2; %Fixed Column Sums
C2=3;
C3=1;
R1=1; %Fixed Row Sums
R2=2;
R3=3;
% Initialize matrix.
m=randi([0 1],rows,columns);
for k=1:rows,
end
runtest = 0 ;
while runtest < 10000000 ;
runtest = runtest + 1 ;
% randomly swap columns
for k=1:columns,
p = randperm(rows);
m(k,:) = m(k,p);
end
if (sum(m(:,[1])) == C1) && (sum(m(:,[2])) == C2) && (sum(m(:,[3])) == C3)...
&& (sum(m([1],:)) == R1) && (sum(m([2],:)) == R2) && (sum(m([3],:)) == R3);
break ;
end
end
R_1 = m(1,1) + m(1,2) + m(1,3);
R_2 = m(2,1) + m(2,2) + m(2,3);
R_3 = m(3,1) + m(3,2) + m(3,3);
%Summing up all the Rows into a array to read
RowsSums= [ R_1 R_2 R_3 ];
C_1 = m(1,1) + m(2,1) + m(3,1);
C_2 = m(1,2) + m(2,2) + m(3,2);
C_3 = m(1,3) + m(2,3) + m(3,3);
%Summing up all the Columns into a array to read
ColumnSums= [ C_1 C_2 C_3 ];
if runtest < 10000000
m
RowsSums
ColumnSums
else
disp('No matrix found within time') ;
end}
0 commentaires
Réponse acceptée
Roger Stafford
le 22 Jan 2015
Modifié(e) : Roger Stafford
le 22 Jan 2015
There is a flaw in the strategy of your code. If at the step
m = randi([0 1],rows,columns);
it does not yield exactly six 1's, you will never succeed in satisfying your sum constraints afterwards using only permutations within each row. At the very least you need to ensure that six 1's in total, no more, no less, are present in the 'm' matrix before you begin with the permutations.
The next problem is that your permutation procedure only permutes elements within each row, which doesn't change the sum of that row. Only a permutation within each column could do that. Hence you need both kinds of permutations, one within rows and one within columns.
You could avoid using the for-loop by making single permutations of the nine elements in 'm' using linear indices. Also this would eliminate the necessity of two kinds of permutations.
m = [ones(1,6),zeros(1,3)];
while ....
m = reshape(m(randperm(9)),3,3);
% check sums
end
Actually it might be easier to leave m always a 1 x 9 row vector to avoid all the 'reshapes' and modify the sum checking procedure accordingly:
sum(m(1:3:7))==R1, etc.
2 commentaires
Roger Stafford
le 22 Jan 2015
These expressions are equivalent:
sum(m(1:3:7))==R1
sum(m([1,4,7]))==R1
sum([m(1),m(4),m(7)])==R1
m(1)+m(4)+m(7)==R1
where m is now a 1-by-9 row vector in accordance with that last idea I put forth which would be equivalent to checking the first row sum of the original 3-by-3 version of m: m(1,1)+m(1,2)+m(1,3)==R1.
You can read about the equivalence of linear indices to matrix indices at the site:
http://www.mathworks.com/help/matlab/math/matrix-indexing.html
Plus de réponses (0)
Voir également
Catégories
En savoir plus sur Logical dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!