A better way to chose a random neighbor

I am building a kind of cellular automata and I have a matrix and I would like to choose a random neighbour of a random position, the following is the way I found I wonder if there is a better more efficient way of doing it:

fil = 10
col = 10
m =  zeros(Int16,fil,col)
m[:,1] .= 1

neighborhood = ((0,1),(0,-1),(1,0),(-1,0) )

for z in 1:length(m)
    i= rand(1:fil) 
    j= rand(1:col)
    if m[i,j]==1
        x=[i,j] .+  rand(neighborhood)

        # check boundaries
    
        if !(x[1] > fil || x[1] <1 || x[2] > col || x[2]<1)
           m[x[1],x[2]] =  1 
        end
   
end 

This allocates an array [i,j] on every iteration. Better to use a tuple (i,j) .+ rand(neighborhood).

I would usually recommend employing ghost cells to avoid these kinds of boundary checks in inner loops.

2 Likes

Thanks! is there an example of how to implement ghost cells?

Anyways that would work for closest neighbours if I have a function that gives a random position with an arbitrary maximum distance e.g.


 x=(i,j) .+  rand_max_distance(fil)

will be more difficult to avoid boundary checks, and something similar would happen with periodic boundary conditions, you would need to use getindex(a, i) = a.a[i % n] as you suggested to avoid in Arrays with periodic boundaries - #4 by stevengj

The “ghost cells” link above has an example. Here is another example, and here is another.

1 Like