2
$\begingroup$

I'm trying to figure out how to create a matrix in mathematica, since I'm just starting working with the program to get a feel before I start graduate school. I'm working through a book problem where I have a 50x50 matrix with each entry being 0, but I need to randomly select an entry and randomly generate either a 1 or 0. After that I need to check if there are any adjacent 1s anywhere in the matrix (if there is a 1 to the left, right, above, or below on the matrix). There obviously won't be any adjacent 1s after the first generation and check, but I need to iterate those two steps, and when there are adjacent 1s, to not update the matrix and instead generate a random entry again. How would I do this?

$\endgroup$
2
  • $\begingroup$ Welcome to MSE. What have you tried? Have you checked the documentation? e.g. this. $\endgroup$ Apr 26, 2021 at 19:06
  • $\begingroup$ Another useful command might be RandomInteger. $\endgroup$
    – bill s
    Apr 26, 2021 at 19:07

1 Answer 1

2
$\begingroup$

You could do this the conventional way where you have a loop, generate random coordinates, see if the nearby entries are 1, retry and so on. However this is awkward because as the matrix is populated more, the random coordinate selection will waste time on entries with 1s in the neighbourhood. It will be very slow.

If instead we convolve the matrix first with a radius 1 cross kernel, this tells us how many 1s there are in the neighbourhood of every entry. We can easily pick out random positions we know will work by finding positions of zeros in the filtered matrix. You can write all of this extremely compactly:

cx = CrossMatrix[1];
m = ConstantArray[0, {50, 50}];
While[MemberQ[(af = ListConvolve[cx, m, 2]), 0, 2],
 {r, c} = RandomChoice@Position[af, 0];
 m[[r, c]] = 1;
];
MatrixPlot[m]

matrix

Update: In the case where you can pick 1 entries and flip them if there are no 1s in the neighbourhood, then I don't think it will terminate but you could cap the number of iterations and use the same method. The only difference is we want the cross kernel to not count the entry it is centered on:

cx = CrossMatrix[1];
cx[[2, 2]] = 0; (* set center kernel cell to zero *)

m = ConstantArray[0, {50, 50}];
iterations = 0;
While[iterations < 10000 && 
  MemberQ[(af = ListConvolve[cx, m, 2]), 0, 2],
  {r, c} = RandomChoice@Position[af, 0];
  m[[r, c]] = Min[RandomInteger[1], 1 - m[[r, c]]];
 ++iterations;
 ]; MatrixPlot[m]
$\endgroup$
3
  • $\begingroup$ I forgot to mention that if the randomly selected entry is already a 1, it is changed back to a 0. But this is still very helpful thank you! $\endgroup$ Apr 26, 2021 at 23:16
  • 1
    $\begingroup$ @mathfanatic33 are you sure, in that case it would never terminate. $\endgroup$
    – flinty
    Apr 26, 2021 at 23:21
  • $\begingroup$ yes because the the question asks for the probability that M(25,25)=1 and when some expression with n going to infinity (not quite there on the math yet), it will converge to the invariant probability $\endgroup$ Apr 27, 2021 at 2:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.