Netlogo Error: "This <turtle> is already dead - netlogo

I am studying flocking behavior in netlogo, and in order to keep track of various flocks I am using a hidden "flock-holder" turtle that I can hatch or let die if a new flock is created or an existing flock runs out of members. I am coming across an issue however, where on occasion when I am trying to interface with some data within a flock, as referred to through an individual member of a flock, I get a message saying "That is dead", causing the code to fail.
From what I understand of the "die" command, if a turtle of any kind dies, it should remove itself from any agentset or variable that references it, and therefore this sort of error shouldn't be a problem? How can I fix or at least debug this strange issue?
Code of my flock-evaluation function that is having the issues below:
to evaluate-flock
if is-in-flock = True ; checking to see if a flock has died out
[
if get-flock-size flock-reference < 2 ; is the turtle the only one in the flock?
[
if verbose = True [ print "Flock has dwindled to nothing" ]
ask flock-reference ; has no more members, so is removed.
[
ask flock-members
[
set flock-reference nobody ; clear any remaining flock members of association with this flock
]
die
]
set is-in-flock False ; no longer in a flock
]
]
ifelse is-in-flock = True ; is turtle in a flock?
[
if verbose = True [ type "This turtle is in flock " print [ who ] of [ flock-reference ] of self ]
if any? other preys in-radius vision with [ is-in-flock = True ] with [ flock-reference != [ flock-reference ] of myself ]; check for nearby turtles that are in different flocks
[
if verbose = True [ print "There are other nearby flocks" ]
let current-school-size ( get-flock-size [ flock-reference ] of self )
if verbose = True [ type "I am part of a school of " print current-school-size ]
let temp-list turtle-set other preys in-radius vision with [ is-in-flock = True ] with [ flock-reference != [ flock-reference ] of myself ] with [ ( get-flock-size flock-reference ) > current-school-size ] with [ subtract-headings ( average-schoolmate-heading [ flock-members ] of flock-reference ) heading < 60]; are any nearby turtles in different, larger flocks that I am alligned with? if so, add them to a list
if count temp-list > 0 ; does the list have any members?
[
if verbose = True [ print "Found a bigger flock" ]
ask flock-reference
[
remove-from-flock myself ; remove myself from my old flock
]
set flock-reference [ flock-reference ] of ( max-one-of temp-list [ get-flock-size flock-reference ] ); join the biggest flock on this list
set is-in-flock True ; sets it to true in case it wasn't for some reason.
]
]
]
[
if verbose = True [ type "Turtle " type [ who ] of self print " is not in a flock" ]
ifelse any? other preys in-radius vision with [ is-in-flock = True ] ; are there any pre-existing flocks the turtle can join?
[
if verbose = True [ print "There are nearby flocks" ]
let potential-flock turtle-set other preys in-radius vision with [ is-in-flock = True ] ; grab any nearby turtles that are already in a flock
***set potential-flock potential-flock with [ subtract-headings ( average-schoolmate-heading ( [ flock-members ] of flock-reference ) ) heading < 60]; remove any that are not aligned with this turtle***
if count potential-flock > 0
[
if verbose = True [ print "There are nearby flocks that I am aligned with" ]
set flock-reference [ flock-reference ] of ( max-one-of potential-flock [ get-flock-size flock-reference ] ); join the biggest flock on this list
set is-in-flock True ; turtle is now in a flock
]
]
[ ; if there are no pre-existing flocks, turtle starts its own
let potential-flock turtle-set other preys in-radius vision with [ is-in-flock = False ] ; Grab any nearby turtles not already in a flock
set potential-flock potential-flock with [ subtract-headings ( average-schoolmate-heading potential-flock ) heading < 60]; remove any that that are not aligned with this turtle
if count potential-flock > 0
[
if visualize-flock-creation = True
[
set color green
ask potential-flock [ set color green ]
wait 0.25
set color blue
ask potential-flock [ set color blue ]
]
if verbose = True [ type "Number of nearby potential flockmates " print count potential-flock ]
hatch-flock-holders 1 ; create a new flock-holder
[
set size 0
set color black ; sets the new flock's placeholder color to the background
set flock-members potential-flock ; adds the list of members to the new flock
ask flock-members
[
set flock-reference myself ; asks the new flock members to add the new flock as their flock-reference
set is-in-flock True ; all these turtles are now in a flock
]
]
]
]
]
end
Potentially unclear variable name reference for code above:
flock-reference: - A variable held by each flocking "prey" turtle, that just points to the hidden "flock-holder" turtle.
flock-members: - An agentset of "prey" turtles that are attached to the hidden "flock-holder" turtle.
I have added an image of the full error message below.
Please let me know if there is any confusion about what's going on here, or if there is anything I can clarify. Thank you!

I can't test this, but I expect that the error stems from agent prey 2 having a reference to a flock-holder that has died. When a flock-holder dies, it is (as you know) deleted from any angentsets that it was a member of and variables that hold a pointer to it are reset to point to nobody. However, NetLogo is smart enough to know that this nobody is a dead flock-holder and gives you the error message you've encountered. If after the error you inspected prey 2, or entered show [flock-reference] of prey 2 at the command line, I expect that you would find that flock-reference was indeed set to nobody.
My guess is that somewhere in your code, not all the prey that were in the (now dead) flock were reassigned to another flock, but rather kept their old value of flock-reference, now nobody. When you ask a flock to die, you might add the line show preys with [flock-reference = nobody]. If there are any, you could track down why.
Hope this helps,
Charles

Related

NetLogo hatch and die

I want to make turtles move around and look for a partner (a turtle that is not already partnered that is on the same patch) , and when they found one I want them to hatch a certain number of turtles and then die. But what happens is that when I start the simulation, all turtles die at the first tick. What am I doing wrong?
to go
ask turtles [
partner-up
]
birth
death
tick
end
to partner-up
if (not partnered?) [
rt (random-float 90 - random-float 90) fd 1
set partner one-of (turtles-at 0 0) with [ not partnered? ]
if partner != nobody [
set partnered? true
ask partner [
set partnered? true
set partner myself
]
]
]
end
to birth
let partnered-turtles turtles with [ partnered? ]
ask partnered-turtles [
calculate-score
hatch (score + 1)
]
end
to death
let partnered-turtles turtles with [ partnered? ]
ask partnered-turtles [
die
]
end
Two things stand out- one is the call to one-of (turtles-at 0 0) with [ not partnered? ]. This includes ALL turtles on the patch that you indicate (equivalent to turtles-here), which means including the turtle executing the command. I think you want other turtles-here or (other turtles-at 0 0).
Next, your 'baby turtles' are inheriting all the attributes of their parents, including values in their partnered? and partner variables. So, the turtles are being hatched with partnered? = true, and so when the call to death occurs in your go procedure, they qualify as partnered-turtles and therefore die. To correct this, you can explicitly set the variables for your hatched turtles- for example:
to birth
let partnered-turtles turtles with [ partnered? ]
ask partnered-turtles [
let score 1
hatch (score + 1) [
set partnered? false
set partner nobody
]
]
end
Also, not sure if this is intentional but wanted to point out that both 'partners' will hatch an offspring. If you want a more standard biological model you may want only one of the parents to hatch.
Revised toy model:
turtles-own [ partnered? partner]
to setup
ca
reset-ticks
ask n-of 10 patches [
sprout 1 [
set partnered? false
set partner nobody
]
]
end
to go
ask turtles [
partner-up
]
birth
death
tick
end
to partner-up
if (not partnered?) [
rt (random-float 90 - random-float 90) fd 1
set partner one-of (other turtles-at 0 0) with [ not partnered? ]
if partner != nobody [
set partnered? true
ask partner [
set partnered? true
set partner myself
]
]
]
end
to birth
let partnered-turtles turtles with [ partnered? ]
ask partnered-turtles [
let score one-of [ 0 1 ]
hatch (score + 1) [
set partnered? false
set partner nobody
]
]
end
to death
let partnered-turtles turtles with [ partnered? ]
ask partnered-turtles [
die
]
end

How can we count agents according to specific variables?

We are trying to solve the following problem:
Each agent has its specific code and at each iteration the list of agents alive in that iteration is updated. We want to calculate how many agents are die of each code present in the list per iteration.
We have these procedures below (code). Obs: We need to use the profile list because of the outputs that are exported by turtle profile
Sorry for the big code below, but we tried our best to reduce it to be reproducible code
Thanks in advance
globals [ ListProfiles Death ]
turtles-own [ profiles-code metabolism-code reproduction-code metabolism reproduction resource-turtle ]
patches-own [ resources ]
to setup
ca
prepare
ask patches [ set resources random 100 ]
let list1 ( list 2 4 )
let list2 ( list 5 10 )
(
foreach list1
[
this-metabolism ->
foreach list2
[
this-reproduction ->
ask n-of 1 patches
[
sprout 1
[
set metabolism this-metabolism
set reproduction this-reproduction
setup-turtles
]
]
]
]
)
reset-ticks
end
to setup-turtles
(
ifelse
metabolism = 2 [ set metabolism-code "M1" ]
metabolism = 4 [ set metabolism-code "M2" ]
)
(
ifelse
reproduction = 5 [ set reproduction-code "R1" ]
reproduction = 10 [ set reproduction-code "R2" ]
)
set profiles-code ( word metabolism-code reproduction-code )
print ( word "profiles-code: " profiles-code )
end
to go
ListProfilesProc
MetaboProc
ProbDieProc
output
tick
end
to ListProfilesProc
set ListProfiles [ ]
ask turtles [
set ListProfiles lput profiles-code ListProfiles
]
set ListProfiles remove-duplicates ListProfiles
end
to MetaboProc
ask turtles [
(
ifelse
metabolism = 2
[
set resource-turtle ( resources - metabolism )
if resource-turtle <= 60 [ DieProc ]
(
ifelse
reproduction = 5
[
if resource-turtle >= 5 [ hatch 1 ]
]
reproduction = 10
[
if resource-turtle >= 10 [ hatch 1 ]
]
)
]
)
]
end
to DieProc
let code profiles-code
foreach ListProfiles [ lp -> ;; I think, here's the problem... I can't individualize the kills by code. I've already tried several things. And therefore I can't get the output of the deaths by code. It is always repeated (general calculation)...
if lp = code
[
set Death Death + 1
]
]
die
end
to ProbDieProc
ask turtles
[
let prob-die random-float 1.01
if prob-die < 0.77 [ DieProc ]
]
end
to prepare
carefully
[ file-delete ( word "output.csv" ) ]
[ ]
file-open ( word "output.csv" )
file-print ( word "code_profile,death,tick" )
file-close
end
to output
file-open ( "output.csv" )
foreach ListProfiles
[
t ->
file-print ( word t "," Death "," ticks )
]
file-close
end
Deaths as you have it is a global variable, which means that any time any turtle accesses it (either to update or read), they are all "sharing" the same value. Instead, you need to track deaths for each profile type. The way you have it, where profiles-code differentiates the different turtle types, you can tackle this a few ways- for example: you could create specific Death trackers for each profile type (eg. Death-M1R1, Death-M1R2... etc.) and output that as needed; or you could use a list, where you update the items in the list that correspond to a specific profile; or you could use a list of lists and use position to grab the death value for a different breed; or you could use the tables extension, which is the example I will show below because I think it's the cleanest and most explicit.
The tables extension allows what is similar to a dictionary structure if you've used that in other coding languages, where you have a {KEY: VALUE} pair such that if you enter the KEY you get out the VALUE. So the general workflow here is to build a dictionary to store the name and death count for each profile type. Then, anytime a turtle dies it will update the death count for its profile type in the dictionary.
To keep it simple, I've made only minor changes to your code above, and added comments where I made (most) updates:
extensions [ table ]
globals [ ListProfiles Death NInitial NFinal R Birth deaths-dict ]
turtles-own [ profiles-code metabolism-code reproduction-code metabolism reproduction resource-turtle ]
patches-own [ resources ]
to setup
ca
prepare
; Define deaths-list as a list
set deaths-dict table:make
ask patches [ set resources random 100 ]
let list1 ( list 2 4 )
let list2 ( list 5 10 )
(
foreach list1
[
this-metabolism ->
foreach list2
[
this-reproduction ->
ask n-of 1 patches
[
sprout 1
[
set metabolism this-metabolism
set reproduction this-reproduction
setup-turtles
; Add each metabolism / reproduction to the deaths dictionary with 0 as initial deaths value
table:put deaths-dict ( word metabolism-code reproduction-code ) 0
]
]
]
]
)
print deaths-dict
reset-ticks
end
to setup-turtles
(
ifelse
metabolism = 2 [ set metabolism-code "M1" ]
metabolism = 4 [ set metabolism-code "M2" ]
)
(
ifelse
reproduction = 5 [ set reproduction-code "R1" ]
reproduction = 10 [ set reproduction-code "R2" ]
)
set profiles-code ( word metabolism-code reproduction-code )
print ( word "profiles-code: " profiles-code )
end
to go
; Stop the model if no turtles exist
if not any? turtles [ stop ]
ListProfilesProc
MetaboProc
ProbDieProc
output
tick
end
to ListProfilesProc
; Simple way to get a sorted list of profile types
set ListProfiles sort remove-duplicates [ profiles-code ] of turtles
end
to MetaboProc
ask turtles [
(
ifelse
metabolism = 2
[
set resource-turtle ( resources - metabolism )
if resource-turtle <= 60 [ DieProc ]
(
ifelse
reproduction = 5
[
if resource-turtle >= 5 [ hatch 1 ]
]
reproduction = 10
[
if resource-turtle >= 10 [ hatch 1 ]
]
)
]
)
]
end
to ProbDieProc
print "Running die proc..."
ask turtles
[
let prob-die random-float 1
if prob-die < 0.4 [
DieProc
]
]
end
to DieProc
; Pull current death count for this profile
let current-profile-death-count table:get deaths-dict profiles-code
; Increase that death count by one
let current-profile-new-death-count current-profile-death-count + 1
; Update the death count in the master dictionary
table:put deaths-dict profiles-code current-profile-new-death-count
die
end
to prepare
carefully
[ file-delete ( word "output.csv" ) ]
[ ]
print "opening..."
file-open ( word "output.csv" )
file-print ( word "code_profile,death,tick" )
file-close
end
to output
file-open ( "output.csv" )
foreach ListProfiles
[
t ->
let profile-deaths table:get deaths-dict t
file-print ( word t "," profile-deaths "," ticks )
]
file-close
end
Output then looks something like:

What is the proper syntaxis when dealing with patch-here in netlogo?

I've got the following code, but when trying to run it I get a message saying "expected a literal value", and it highlights calidad...
I'm guessing it is because there is a problem with how i am writting the brackets?
to check-if-dead
if habitat = "escarabajo" [
ask escarabajos [
if count escarabajos-here > capacidad-de-carga-bosques [die] ; beetles that reach patches that already have a # above the carrying capacity die
if patch-here = [calidad "baja"] [
if random 100 > probabilidad-de-supervivencia-calidad-baja [die]
]
if patch-here = [calidad "alta" ] [
if random 100 > probabilidad-de-supervivencia-calidad-alta [die]
]
]
]
There is patches of high quality and patches with low quality in my universe, and I want the turtles to die with a certain probability (determined by a slider), depending on which patch they land...
You probably want if [calidad] of patch-here = "baja":
to check-if-dead
if habitat = "escarabajo" [
ask escarabajos [
if count escarabajos-here > capacidad-de-carga-bosques [die] ; beetles that reach patches that already have a # above the carrying capacity die
if [calidad] of patch-here = "baja" [
if random 100 > probabilidad-de-supervivencia-calidad-baja [die]
]
if [calidad] of patch-here = "alta" [
if random 100 > probabilidad-de-supervivencia-calidad-alta [die]
]
]
]
end
But note that turtles always live on a patch, so you are allowed to just reference the patches-own variable directly as a short-cut for this situation (same way you can use pcolor in a turtle context, too):
to check-if-dead
if habitat = "escarabajo" [
ask escarabajos [
if count escarabajos-here > capacidad-de-carga-bosques [die] ; beetles that reach patches that already have a # above the carrying capacity die
if calidad = "baja" [
if random 100 > probabilidad-de-supervivencia-calidad-baja [die]
]
if calidad = "alta" [
if random 100 > probabilidad-de-supervivencia-calidad-alta [die]
]
]
]
end

Catch nobody for target patch

I want to check if target patches fulfil a condition. If a patch is found that fulfils the condition,
then the turtles should move there. If 'nobody' fulfils this condition, then an error message should be printed.
The condition is that a patch should have in radius 10 2 turtles of the same breed.
I try to achieve this with ifelse and nobody. However, at the moment I always get the error message, even though the
target variable is not empty (you can check this with the if loop).
breed [ breed1s breed1 ]
breed [ breed2s breed2 ]
globals [target1 target2]
to setup
ca
create-breed1s 1000 [
setxy random-xcor random-ycor
]
create-breed1s 1000 [
setxy random-xcor random-ycor
]
end
to go
ask turtles [
set target1 ( count turtles in-radius 10 with [breed = breed1s] ) >= 2
set target2 ( count turtles in-radius 10 with [breed = breed2s] ) >= 2
new-position
]
end
to new-position
ifelse target1 != nobody
[ if (breed = breed1s) [ move-to one-of patches with [ target1 ] ] ]
[ print "Not enough agents in the neighborhood" ]
ifelse target2 != nobody
[ if (breed = breed2s) [ move-to one-of patches with [ target2 ] ] ]
[ print "Not enough agents in the neighborhood" ]
; if (breed = breed1s)
; [ move-to one-of patches with [ target1 ] ]
end
A remark to the efficiency of the model: as I want to add turtles later in every tick, target has to be reevaluated
in every tick (therefore it is in "go" and not in "setup").
Another question: is there a possibility to do something like [ breed = myself ] instead of [ breed = breed1s ], so
I don't have to type the breed for every breed?
Edit:
the turtles that move to the target patch should have the same breed that is also addressed in the target patch.
The problem is actually how you are creating target1, not the check as to whether it is nobody. You have:
set target1 ( count turtles in-radius 10 with [breed = breed1s] ) >= 2
This line first identifies all the nearby turtles with the appropriate breed and counts them. If the count is 2 or higher, then the variable target1 is set to true and to false if the count is 0 or 1. So you are comparing a boolean true or false to nobody (a special type of agent). That will always be a mismatch and therefore print the error.
Just a note on debugging - when you get this sort of problem, it's always useful to have a print statement for each side of the check just before doing the check. You would have immediately spotted that target1 wasn't what you thought it was.
Since you are asking to move to one-of the patches, you probably really want to store the available patches that are within 10 distance (I think) and have enough of the right type of turtles. So, you need something like:
to go
ask turtles [
set target1 patches in-radius 10 with [count breed1s-here >= 2]
set target2 patches in-radius 10 with [count breed2s-here >= 2]
new-position
]
end
Then your emptiness test is any?
to new-position
ifelse any? target1
[ move-to one-of target1 ]
[ print "Not enough agents in the neighborhood" ]
ifelse any? target2
[ move-to one-of target2 ]
[ print "Not enough agents in the neighborhood" ]
end
Assuming I have correctly interpreted that you want patches within 10 of the asking turtle (as compared to any patch with sufficient turtles within a distance of 10) and all you care about is the number of turtles of its own breed, then:
to go
ask turtles [
let target-breed [breed] of myself
set targets patches in-radius 10 with [count turtles-here with [breed = target-breed] >= 2]
new-position
]
end
to new-position
ifelse any? targets
[ move-to one-of targets ]
[ print "Not enough agents in the neighborhood" ]
end
On the efficiency, it depends on how many turtles you have. If you have quite a lot of turtles, then asking each to count its own neighbourhood will be expensive. Instead, you could have patchsets for each breed. That is, set up target1 as patches with [count breed1s-here >= 2] at the beginning of the go procedures. Then you can just do:
to go
let targets1 patches with [count breed1s-here >= 2]
let targets2 patches with [count breed2s-here >= 2]
ask turtles
[ set targets targets1 in-radius 10
new-position
]
end
However, you can no longer use the breed of the turtle and the myself trick to pick the correct patchset. There are ways to get around this (for example, using a list with two items, breed at first position and the patchset as second position) but that's getting well off track for this answer.
to new-position
ifelse any? targets
[ move-to one-of targets ]
[ print "Not enough agents in the neighborhood" ]
end

Preferential attachment: Selecting a node to attach

I've been struggling with this one for the last 24 hours or so I feel like I'm missing something relatively simple here.
to setup-scale-free-network
clear-all
;; Make a circle of turtles
set num-nodes (num-children + num-adults + num-toddlers)
create-children num-children
create-adults num-adults
create-toddlers num-toddlers
layout-circle turtles (max-pxcor - 8)
ask turtles[
create-links-with turtles with [self > myself and random-float 5 < probability]
]
setup
end
to-report find-partner
report [one-of both-ends] of one-of links
end
The above code creates a set number of turtles of various breeds and creates a number of links between these breeds.
to go
reset-ticks
make-link find-partner
tick
end
The two procedures would be called until the needed level of degree distribution as been met.
What I want to do is use the find-partner procedure to move towards preferential attachment to do this I need to modify this code to create a link from the node find partner has selected to one of each of the other three types of breeds in my network.
to make-node [old-node]
crt 1
[
set color red
if old-node != nobody
[ create-link-with old-node [ set color green ]
;; position the new node near its partner
move-to old-node
fd 8
]
]
end
My own attempts have lead no where to be honest. I know I'm asking for a lot of help but I'm at my wits end here, thank you for your help and patience.
I was unable to completely understand your question. I am guessing that you wish to create another type of link which you call preferential attachment (with green color) between turtles who are already a part of the network.
One thing you might want in this situation is that you do not pick turtles which are already in a preferential attachment network. [this is just my assumption]
I have modified your code (as follows) to get the desired network with preferential attachment shown with green colored links, have added a turtle-variable already-attached which is used to exclude turtles which are already preferentially attached to others.
Hope this helps!
breed [ children child ]
breed [ adults adult ]
breed [ toddlers toddler ]
children-own [ already-attached ]
adults-own [ already-attached ]
toddlers-own [ already-attached ]
to setup-scale-free-network
clear-all
let num-children 5
let num-adults 5
let num-toddlers 5
let probability 1
;; Make a circle of turtles
create-children num-children [ set color orange ]
create-adults num-adults [ set color green ]
create-toddlers num-toddlers [ set color blue ]
layout-circle turtles (max-pxcor - 8)
ask turtles
[
create-links-with turtles with [self > myself and random-float 5 < probability]
]
end
to go
setup-scale-free-network
ask turtles with [already-attached = 0]
[
attach-to-one-of-each-breed self
]
end
to attach-to-one-of-each-breed [ source-node ]
ask source-node
[
if any? other children with [ already-attached = 0 ]
[
ask one-of other children
[
set already-attached 1
create-link-with source-node [ set color green ]
]
]
if any? other adults with [ already-attached = 0 ]
[
ask one-of other adults
[
set already-attached 1
create-link-with source-node [ set color green ]
]
]
if any? other toddlers with [ already-attached = 0 ]
[
ask one-of other toddlers
[
set already-attached 1
create-link-with source-node [ set color green ]
]
]
]
end