menu

Neighboorhood retrieval (gridmodels)

In a grid-based model, the next state of a grid point is often influenced by its neighbours. An array of functions is available in Cacatoo to get information on neighbours in the Moore or Neumann neighboorhood (see table below). Each compass direction is also linked to a number (0 is self, 1 is North, etc) which can be used to extract specific neighbours.

Moore neighbourhood
516
203
748
Neumann neighbourhood
1
203
4


Directly retreiving neighbours

To get a single neighbour from one of these neighbourhood, you can use the following function:
getNeighbour(model, col, row, direction)

For example, to get the 'North-West' neighbour (5) directly within the nextState function, you can use:
this.getNeighbour(this, i, j, 5)

To get multiple neighbours corresponding to a certain "type", store them in an array, you can use getNeighbours (plural!):
getNeighbours(model, col, row, property, value, neighbour_array)

For example, to get the 'North' and 'South' neighbour (1 and 4), you can use:
this.getNeighbours(this, i, j, [1,4])

If you want to use one of the default neighbourhoods, you can use one fo the following shortcuts:

getNeighbours8(model, col, row, property, value, neighbour_array) // Moore, self exclusive
getNeighbours9(model, col, row, property, value, neighbour_array) // Moore, self inclusive
getNeighbours4(model, col, row, property, value, neighbour_array) // Neumann, self exclusive
getNeighbours5(model, col, row, property, value, neighbour_array) // Neumann, self inclusive



Standardised functions are also available to count, sum, or sample from adjacent grid points, listed below.

Summing a property of all neighbours

sumNeighbours(model, col, row, property, neighbour_array)

The neighbour array can be any array which includes all neighbours ([0,1,2,3,4,5,6,7,8]) or only a few ([0,4,6]). A few frequently used neighbourhoods can be called like this:

sumMoore8(model, col, row, property, value)
sumNeighbours8(model, col, row, property, value) // same as above, different name
sumMoore9(model, col, row, property, value)
sumNeighbours9(model, col, row, property, value) // same as above, different name
sumNeumann4(model, col, row, property, value)
sumNeighbours4(model, col, row, property, value) // same as above, different name
sumNeumann5(model, col, row, property, value)
sumNeighbours5(model, col, row, property, value) // same as above, different name



Counting all neighbours with 'property' set to 'value'

countNeighbours(model, col, row, property, value, neighbour_array)

The neighbour array can be any array which includes all neighbours ([0,1,2,3,4,5,6,7,8]) or only a few ([0,4,6]). A few frequently used neighbourhoods can be called like this:

countMoore8(model, col, row, property)
countNeighbours8(model, col, row, property) // same as above, different name
countMoore9(model, col, row, property)
countNeighbours9(model, col, row, property) // same as above, different name
countNeumann4(model, col, row, property)
countNeighbours4(model, col, row, property) // same as above, different name
countNeumann5(model, col, row, property)
countNeighbours5(model, col, row, property) // same as above, different name



Getting a random neighbour

randomNeighbour(model, col, row, neighbour_array)

The neighbour array can be any array which includes all neighbours ([0,1,2,3,4,5,6,7,8]) or only a few ([0,4,6]). A few frequently used neighbourhoods can be called like this:

randomMoore8(model, col, row)
randomNeighbours8(model, col, row) // same as above, different name
randomMoore9(model, col, row)
randomNeighbours9(model, col, row) // same as above, different name
randomNeumann4(model, col, row)
randomNeighbours4(model, col, row) // same as above, different name
randomNeumann5(model, col, row)
randomNeighbours5(model, col, row) // same as above, different name



Roulette wheel selection

This is similar to random neighbour selection, but you can assign a grid point property to do weighted sampling:
rouletteWheel(gridpoints, property)
For example, to sample an individual with 'fitness' as weight, you can do:
this.getNeighbours(gridpoints, property)
rouletteWheel(gridpoints, property)

The neighbour array can be any array which includes all neighbours ([0,1,2,3,4,5,6,7,8]) or only a few ([0,4,6]). A few frequently used neighbourhoods can be called like this:

randomMoore8(model, col, row)
randomNeighbours8(model, col, row) // same as above, different name
randomMoore9(model, col, row)
randomNeighbours9(model, col, row) // same as above, different name
randomNeumann4(model, col, row)
randomNeighbours4(model, col, row) // same as above, different name
randomNeumann5(model, col, row)
randomNeighbours5(model, col, row) // same as above, different name



Getting or setting a grid point at arbitrary position:
When programming, you may often want to 'get' or 'set' objects. To do this with gridpoints, you need to know the coordinates of these grid points, and modify them with 'getGridpoint' and 'setGridpoint'. Note that the i,j coordinates will automatically wrap arround the grid.
getGridpoint(i, j)
setGridpoint(i, j, template_gridpoint)
So for example, to get a random grid point in the entire grid, and copy it to a random position, you can do: sim.model.rng.genrand_int
let x_get = sim.rng.genrand_int(0,sim.ncol)
let y_get = sim.rng.genrand_int(0,sim.nrow)
let template = this.getGridpoint(x_get, y_get)
let x_set = sim.rng.genrand_int(0,sim.ncol)
let y_set = sim.rng.genrand_int(0,sim.nrow)
this.setGridpoint(x_set, y_set, template)

Neighboorhood retrieval (flockmodel/boids)

For flockmodels, there are two important functions for neighbourhood retreival. Firstly, this function gets the boids in range (where range is 20)
let neighbours = this.getIndividualsInRange(boid.position, 20)
But you may also want to select the gridpoints of a model that corresond to this boids position. This happens via this function, here with range 5:
let gps_in_range = this.getNearbyGridpoints(boid,sim.gridmodel,5)