Using MATLAB to create a latin square matrix

796 views Asked by At

I'm pretty rusty at MATLAB and I'm trying to brush up by automating some Latin square problems. The code I'm working on is as follows:

counter=1;
for i=1:10
    for j=1:10
        if A(i,j)=0
            A(i,j)=[This is where I'm stuck];
        end
        counter=counter+1;
    end
end    

I would like this code to check the values in A(i,j) to determine whether or not a value from [1,...,n] is already present in the ith row, and then pick random value from

[1,...,n] excluding [values already present].

Basically I'm just trying to brute force the completion of partial latin squares.

Edit:

I'm not trying to generate random latin squares, but rather ones with certain properties in place. For example, suppose we have the following setup:

A=[X,0,0,0,Y,0,0,0,Z]

Where 0,X,Y,Z are all 3x3 submatrices and X,Y,Z have values from 1,...,9 in them. I'm trying to devise an automated approach to completing a partial latin squares which have some values in place.

1

There are 1 answers

4
Wolfie On

The method you describe isn't robust enough to generate a Latin square every time. For instance, imagine we are calculating the 2nd row of a 5x5 square

1 2 3 4 5
2 4 1 3 ?

The first 4 columns obeyed the rules, choosing random values in each column which don't result in a row/column clash. Then the last value must be a 5 which isn't allowed. You could add another stage which would cycle through clashes and make swaps, but this could be endless if not carefully constructed!

A much easier method would be to construct a "simple" Latin square of size n with the following form:

A = [1    2    3    ...    n-1  n
     n    1    2    ...    n-2  n-1
     n-1  n    1    ...    n-3  n-2
     ...  ...  ...  ...    ...  ...
     3    4    5    ...    1    2  
     2    3    4    ...    n    1   ]

Each row is the vector 1:n permuted by one element each row. This can be generated easily in Matlab using toeplitz:

A = toeplitz([1,n:-1:2],1:n);

Now we have a Latin square! You could randomise this process by making the row permutations random, not ordered. We can do this afterwards, and permute the columns too, using random indices from randperm

A = A(randperm(n), randperm(n));

Note, this won't yield all of the possible Latin squares, since:

"Two squares are in the same isotopy class if one can be obtained from the other by permuting rows, columns and symbols" Brendan McKay

Looking at hopping between classes would be another level. There are over 1 million classes for n=8, and the number of classes explodes rapidly for higher values! Wikipedia


Since there are 9,982,437,658,213,039,871,725,064,756,920,320,000 Latin squares for n=10 (as in your attempt) I think it's safe to say neither your brute force method nor this permutation method will exhaust them quickly anyway!


Disclosure: this answer was based on gnovice's comment, which was worth expanding on for context and links.