# Random matrix with no repeats in rows and columns.

5 views (last 30 days)

Show older comments

So I have generated a random matrix with dimensions 10x15 with values between 2 and 18 with step length 2.

Simple code:

candidates = 2:2:18;

idx = randi(numel(candidates), 10, 15);

M = candidates(idx)

So my questions is how do I do to never get a value above, under or next to the same value. As the ones I have marked with red in the picture.

##### 5 Comments

the cyclist
on 25 Nov 2021

### Accepted Answer

Jan
on 25 Nov 2021

Edited: Jan
on 26 Nov 2021

Create the matrix elementwise. Choose a random element from the available elements. Exclude elements on top and left of the element to be set:

nx = 15;

ny = 10;

pool = 1:9; % Choose values 1:9, multiply by 2 finally

M = zeros(ny, nx);

for ix = 1:nx

for iy = 1:ny

% Exclude elements on the left and on the top from pool:

exclude = [M(gt0(iy - 1), ix), M(iy, gt0(ix - 1))];

choose = pool;

choose(exclude) = [];

% Nicer but slower in one line:

% choose = setdiff(pool, [M(gt0(iy - 1), ix), M(iy, gt0(ix - 1))]);

% Choose a random element from the remaining list:

M(iy, ix) = choose(randi(numel(choose)));

end

end

M = M * 2

function k = gt0(k)

% Reply [] as index, if it is <= 0

if k <= 0, k = []; end

end

I've experimented with cumsum(cumsum(randi([1, 9], 10, 15), 1), 2): There are no repetitions. Then limit the values by rem(). This was not successful. In one dimension it is working, but not in 2.

##### 6 Comments

Image Analyst
on 26 Nov 2021

Latin Squares are a very important concept in the "Design of Experiments" (DOX).

Actually there is Latin Square code in the File Exchange:

### More Answers (2)

the cyclist
on 26 Nov 2021

Edited: the cyclist
on 26 Nov 2021

I believe this does what you want.

% Set the random number seed, for reproducibility

rng default

% The pool of random numbers to choose from

pool = 2:2:18;

% The size of the array

M = 10;

N = 15;

% Preallocate the output array

out = zeros(M,N);

% Fill the upper-left element from the pool

out(1,1) = randsample(pool,1);

% Fill the first column, never repeating the just-above value

for i1 = 2:M

out(i1,1) = randsample(setxor(pool,out(i1-1,1)),1);

end

% Fill the first row, never repeating the just-left value

for j1 = 2:N

out(1,j1) = randsample(setxor(pool,out(1,j1-1)),1);

end

% Fill the rest of the array, never repeating the just-above and just-left values

for ii = 2:M

for jj = 2:N

out(ii,jj) = randsample(setxor(pool,[out(ii-1,jj),out(ii,jj-1)]),1);

end

end

out

I would caution you, though, that I have not thought carefully about the random properties of this array. (For example, does each element have equal probability for each value, etc., that might be important to you.) I think it's probably OK.

Also, if you do not have the Statistics and Machine Learning Toolbox, you will not have the randsample function, and therefore will need to replicate that function's behavior.

### See Also

### Community Treasure Hunt

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

Start Hunting!