Reputation: 1
My NetLogo model starts with an initial population of turtles with species = 1 that are randomly distributed on a world with 5 habitats (called sectors in the model). The turtles can move freely across all sectors and reproduce but have variables that control their diet and phenotype. My procedure for check-speciation is based on the phenotype variables (pheno-value) of turtles and the sector they are on. It calculates the average pheno-value in each sector then calculates the difference in average pheno-value between each sector. If this difference exceeds a set threshold, than all turtles in that sector become a new species and their species value increases.
I get different variations of this error "Can't find element 5 of the list [0 0 0 0 0], which is only of length 5" every 2-4 model run because of the "foreach" command I use in this code. Are there any edits I can make to have it run more consistently?
To update the turtles' species, I use "ask turtles with [sector = s]". I'm wanting it to change the species of every turtle in that sector resulting in 1 new species composed of turtles in that sector; however, I think its giving each individual turtle in that sector a new distinct species value resulting in as many new species as there are turtles. How does "ask turtles with" work on groups of turtles? Is there a way to make all turtles in a sector change the same way?
This is my code:
to check-speciation
let sector-list sort remove-duplicates [sector] of patches with [ any? turtles-here ]
let turtle-counts-per-sector []
let avg-pheno-per-sector []
let max-turtle-count 0
let max-sector 0
let sector-differences []
foreach sector-list [
s ->
let count-turtles count turtles with [sector = s]
set turtle-counts-per-sector lput count-turtles turtle-counts-per-sector
let avg-pheno mean [ pheno-value ] of turtles with [ sector = s ]
set avg-pheno-per-sector lput avg-pheno avg-pheno-per-sector
if count-turtles > max-turtle-count [
set max-turtle-count count-turtles
set max-sector s
]
let difference ( max avg-pheno-per-sector ) - item (s - 1) avg-pheno-per-sector
set sector-differences lput difference sector-differences
if item ( s - 1 ) sector-differences >= speciation-threshold
[ask turtles with [ sector = s ] [
let new-species ( 1 + max species-list )
set species new-species
set species-list lput new-species species-list
set pheno-value 0
]
]
]
end
I changed "item s" to "item ( s - 1 )" because I would get the "can't find element of list" error on every model run. This fixed the issue for most model runs but I will keep getting the error every so often and I can't figure out how to stop it.
species-list holds all the species values are present in the model and using "1 + max species-list" makes sure a new species value is used when speciation occurs (otherwise if 2 sectors of turtles initially have species = 1, they'd both change to species = 2 despite being different sectors). This is why I think "[ask turtles with [ sector = s ] [" is affecting each turtle within a sector individually because I will randomly get an absurd amount of new species. How do I get all the turtles in a sector to have the same new species value?
Upvotes: 0
Views: 51
Reputation: 9610
The ask
problem: create the new species number as the first thing you do in the if
, before the ask, and then use it inside the ask
. Otherwise, each asked turtle will increment the number.
The s
problem: you have values in your sector list too large for the length of the lists you use item
on. Use print (word s " vs " lst)
(where lst
should be your list) before each call to item
in order to see this. In NetLogo, debugging typically starts with print
commands.
Upvotes: 1
Reputation: 1736
I didn't take time to look at your code carefully, but my immediate suspicion is that the problem statement is:
let sector-list sort remove-duplicates [sector] of patches with [ any? turtles-here ]
Could it be that occasionally there are no turtles on one or more sectors, so this list has fewer than 5 members? If so:
Try making sector-list a global variable that always holds the sector values
Change this code:
foreach sector-list [ s -> let count-turtles count turtles with [sector = s] set turtle-counts-per-sector lput count-turtles turtle-counts-per-sector let avg-pheno mean [ pheno-value ] of turtles with [ sector = s ]
so it deals with sector numbers that have no turtles on them:
let turtles-on-sector turtles with [sector = s]
ifelse any? turtles-on-sector
[ do this ]
[ or do this if no turtles ]
Otherwise, your approach seems generally very good!
Steve R.
Upvotes: 1