Latin Square

조회 수: 13 (최근 30일)
eddie ball
eddie ball 2011년 8월 15일
편집: Xin Niu 2020년 9월 13일
I am trying to create a matlab function that returns the number of latin squares for a given size n (where n is around 5). I would like to do this simply by checking all matricies of size n (where the matrix is filled with number 1-n). I am hoping to make it more efficient later but this is my start but i am stuck at trying to figure out how to get matlab to change the matrix by one number. for example, starting with a matrix
M = [3 3 3; 3 3 3; 3 3 3] checking to see if its a Latin square, then checking the next matrix
M = [3 3 3; 3 3 3; 3 3 2]
then
M = [3 3 3; 3 3 3; 3 3 2]
then
M = [3 3 3; 3 3 3; 3 3 1]
then
M = [3 3 3; 3 3 3; 3 2 3]
...
I can do this if i assume a value for n, but without this assumption i cant figure it out. If i knew n, i could just do 9 for loops, but if n were 4 for example, the code would need to be changed to have 16 for loops.
Any help would be greatly appreciated.
Thankyou
  댓글 수: 1
Xin Niu
Xin Niu 2018년 9월 25일
편집: Xin Niu 2020년 9월 13일
Hi, I also had similar questions and finally figured out an answer. Here is my code:
If you use for loop to fill the numbers, the problem is that the codes are different for even and odd input N. And it's more efficient to use circshift function. Also, in most cases we may prefer to create a latin square with interleaved orders which has better order balance like this:
CreateLatinSquare(5)
ans =
1 2 5 3 4
2 3 1 4 5
3 4 2 5 1
4 5 3 1 2
5 1 4 2 3
(note that in all the rows, the case 3 before 4 and 4 before 3 are balanced)

댓글을 달려면 로그인하십시오.

답변 (4개)

Jan
Jan 2011년 8월 15일
You actually look for a method to create combinations with repetitions. There are some functions in the FEX for this task - I assume this one is the fastest: FEX: VChooseKRO, but you need a C-compiler to install it. FEX: Combinator is an efficient method in pure Matlab.
Another method would be the direct approach:
ready = false;
k = ones(1, n*n);
jj = n*n;
while not(ready)
<here do the check for the vector k>
j = jj;
k(j) = k(j) + 1;
while k(j) > n
k(j) = 1;
j = j - 1;
if j == 0
ready = true;
break;
end
k(j) = k(j) + 1;
end
end
  댓글 수: 1
eddie ball
eddie ball 2011년 8월 16일
hey thanks alot! i want to see if i can use a direct approach, and will see if i can use what you have shown me
thanks again

댓글을 달려면 로그인하십시오.


Walter Roberson
Walter Roberson 2011년 8월 15일
You could adapt the "odometer" algorithms from this old discussion. I know I have implemented it in MATLAB more than once. I didn't bother specifically saving the code as it becomes easy to reproduce once one grasps the idea of the algorithm.
  댓글 수: 2
Jan
Jan 2011년 8월 15일
For an adaption, see my answer...
eddie ball
eddie ball 2011년 8월 16일
hey thanks for the advice, i will look into it and see if i can use it

댓글을 달려면 로그인하십시오.


Image Analyst
Image Analyst 2011년 8월 16일
Those don't look like Latin Squares as I know them. You give row vectors instead of actual square matrices like the squares on the Wikipedia page. I have Visual Basic code for generating Latin Squares if you need it. Have you seen the Wikipedia page with the formula for number of Latin Squares as a function of n? http://en.wikipedia.org/wiki/Latin_square
  댓글 수: 1
eddie ball
eddie ball 2011년 8월 16일
lol yeah i typed them as matricies but i guess i didnt enter it in correctly.
I did look at the wikipedia page and i saw the answers but i wanted to see if i could write a code to get those answers. If at all possible id love to see the Visual Basic code for generating latin squares.
Thanks!

댓글을 달려면 로그인하십시오.


Xin Niu
Xin Niu 2020년 9월 13일
편집: Xin Niu 2020년 9월 13일
perhaps this will be faster?
n=5;
latinSquare=nan(n);
latinSquare(:,1)=1:n;
shiftsize=(.5-mod(1:n-1,2))/.5.*ceil((1:n-1)/2);
for col=2:n
latinSquare(:,col)=circshift((1:n)',shiftsize(col-1));
end

카테고리

Help CenterFile Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by