How can I change a turtle's status depending on specific conditions? - netlogo

I really need your help to fix a problem with my code.
Unfortunately, I am having difficulty by updating the status of turtles once a condition is satisfied.
It is a virus spread problem: each node, called human, has its own 'bag' which contains different items (virus and medicines). The bag is made up of items from the neighbours that are linked to the chosen turtle.
The virus can come from a zombie at the beginning (t=0) and move from turtle to turtle, depending on what they decide to do. If a turtle picks up a virus (spread action), it can become infected.
The part of code that is giving me some problems is the following:
to spreading
ask one-of humans
[ let choice one-of out-link-neighbors
ifelse empty? bag
[ ifelse random-float 1 < p
[action1 set bag lput act1 bag print "act1"]
[action3 print "act3"]
]
[spread set bag lput spreadvirus bag print "spreadvirus"
if [infected?] of choice
[become-infected] ]
]
]
end
more specifically the part with spread.
What that part of code should do is to build for each randomly chosen turtle a bag made up by all the'items' from neighbours' bags, and transform that turtle according to what it chooses.
For example, as you can see in the figure below, at the beginning nodes 2,5 and 7 can be potentially infected because they are linked to the zombies. Each turtle can 'see' all its items plus all the items contained in its neighbours bags (for example, 7 can see - and potentially choose - all the items from Z, from 8 - its bag is empty in this case - and from its own bag, made by historical stored items, i.e. past choices). Let's say that 7 picks the virus from the zombie (action 2, i.e. spread) and becomes infected. Node 5, that can see all the items contained in the lists of nodes 4 and 7, can become infected as well, depending on what it chooses. If 5 prefers an item from 4, that is a node not infected because in its own list there are only uninfected items, it becomes susceptible. If it chooses, among all, the infected item from 7, it becomes infected as well. And so on...
What I suspect is that the bags are not storing information from the neighbours as I want. This explains why no humans are becoming infected from the ifelse statements, but only susceptible and they change color in white and blue depending on their choices.
I am not getting any error from the code, so it is difficult for me to understand what I am really doing wrong. I also put some print to see what is not working, and it seems that the part of code with spread as action is the problem.
What I should expect is a list that contains all the items from turtle's neighbours. At each tick the turtle can choose what to do with those items (action1, spread, action3), by adding a new item, selecting an item from neighbours, or do nothing. This choice should be added to the turtle bag. This means that the list, at each tick, should be updated, taking into account all the elements from the neighbours, plus the selected action/element from the turtle. But the turtle becomes infected only if it chooses (spread) not a medicine from the neighbours, but a virus.
UPDATED after JenB answer and to better explain how the human breed should become infected:
The possible types of items that each bags can contain are new medicines, medicines from the same turtle or from neighbours and/or virus, for humans; only virus for zombies - I do not need to add elements to zombies' bags.
To better clarify: Once there is a link between one turtle and another one, these turtles can have access to all the items in their bags, respectively. When it is time to select an action, the turtle can have access to its own bag that contains all the items stored from the neighbours’ bags, as bags are made up of items (medicines and virus) from all the turtles linked to a chosen turtle.
However, the turtle becomes infected only if it decides to select the action spread, and to select an item infected from the neighbors’ bags.
After the choice, the element chosen is added to its own bag.
I edited part of the code. What I did is to create a new bag for zombies, initialising with only "virus"; furthermore, I edited the part of code regarding 'to spread' as following:
to spread
set action1? false
set spread? true
ifelse any? out-link-neighbors with [infected?]
[ print "Virus!"
set spreadvirus spreadvirus + 1
become-infected]
[ print "Medicine from neighbour"
set spreadvirus spreadvirus + 1
become-susceptible]
end
But also in this way, I am not having humans that become infected. And I think that the bag that I am trying to build is not storing all the items from the turtle's neighbours. And this explains why turtles cannot become infected.
I hope you can help me to understand what I have done wrong.
Thank you for your time, effort and help.

That's a much clearer explanation of what should happen, but you still haven't told us what is happening. For example, you have print statements in there, is the appropriate output being printed (so the code is getting to that part) or is that bit of the code not being selected? Are you getting an error message? What does one of these lists look like?
I think you mean that the logic is not working. I suggest you put some more diagnostic prints at the top once you have selected the human:
ask one-of humans
[ type "Neighbour count: " print count out-link-neigbors
type "Bag at start: " print bag
ifelse...
Then you can see why the selected path is being selected. It will also let you know if the variable contents aren't what you expect.
You have a comment that the line set bag lput spreadvirus bag is not working. So replace:
[ show one-of bag
set bag lput spreadvirus bag ;; NOT WORKING
print "spreadvirus" ]
with
[ show bag
set bag lput spreadvirus bag
show bag
print "spreadvirus" ]
to see what it is doing.
The other thing you can do to debug is replace ask one-of human with 'ask human 10` (or some other specific human). Find humans with different situations - one with only one neighbour for example, and try them out.
UPDATED in response to comment
The [6 2] is the contents of the bag. When you put act1 or spreadvirus or whatever into the bag, you are putting a number into the bag. This is because act1 and spreadvirus are numbers. They start as 0 and you add 1 to them at various points in your code.
It seems to me that you have put the wrong things in the bag. If you want a human to become infected if they pull out an infected item from the bag, then the bag needs to contain infected and uninfected items, not numbers.

Related

Monitor the lifecycle of each turtle (NetLogo)

I have a question on how to "monitor" through time some turtles. You can think of this problem like plotting the lifecycle of each turtle.
Let's say initially I have 5 turtles. At each tick, a new turtle is created.
They do some actions (e.g., each of them interacts with a dummy turtle) before their death.
I can identify the turtle created at each tick using who.
I have tried as follows:
create-temporary-plot-pen (word "Turtle " (who))
set-plot-pen-color color
plotxy ticks count XX ;(# of interactions between who and the dummy variable through time)
but nothing is displayed on the chart. Only the list of turtles that at each tick are created is correctly displayed.
The desired plot should show how many times each turtle interacts with the dummy variable before it dies.
I hope it makes sense to you. If it does not, I will be happy to answer all the question you can have.

Is there a way in netlogo to get a turle to leave the simulation area and then come back after a certain number of ticks?

I am working on a evacuation simulation, my turtles represent vehicles that leave an area, I currently do this by having the turtle die when it reaches the evacuation point, however I would like to have the vehicle return show up elsewhere on the map and return to the original point of origin (to pick up more passengers to evacuate) I am unsure hide turtle will do this properly, because I don't want the turtle interacted with while it is "off the map" Is there a way to do what I want?
Jon,
Two ways I can think of.
One would be to indeed make the vehicle hidden and then have all your normal interactions with turtles be instead with vehicles with [not hidden?]. You could then refer to the hidden vehicles as vehicles with [hidden?]. I'm assuming that you have a vehicles breed, but if all turtles are vehicles, then it would be turtles with [not hidden?], etc.
But breeds suggests a different approach. Turtles can change their breeds, so if you have a breed vehicles, then you could create another breed (say) inactive-vehicles. When a vehicle has reached the evacuation point, you could ask it to set breed inactive-vehicle and set hidden? true. You could then continue to refer to active cars as vehicles and these inactive cars as inactive-vehicles. So, ask vehicles ... will just refer to those that are still active. You could then ask inactive-vehicles to go wherever you wish and then reset their breed to vehicles. (I'm not sure inactive-vehicles is great breed name, but it can be anything you want.)
Hope this helps,
Charles

In a Netlogo network, how can turtles "see" properties of other turtles?

I am trying to build a model in which turtles decide to change colour depending on their environment in a network.
The approach would be to "check" the colour of the surrounding turtles and then set an if statement for the turtle in question to switch colour (there will only be 2 colours).
Specifically I would like to know how can a turtle "see" or check other turtles' colour (or other properties).
If possible I would also like to create a slider for "how many links away" can turtles see their neighbouring turtles' (or neighbours of neighbours, etc) colour.
I am new to both Netlogo and Stackoverflow, so please let me know if I should make any modifications to my model and/or question.
Thanks!
Welcome to Stack Overflow! Typically you'll want to stick to a single question per post, both for simplicity and for the benefit of future users with similar questions. As well, in cases where its applicable you should try to include some code to show what you've tried so far, as well as any setup necessary- you want to make a minimal, complete, and verifiable example. In this case, I think you're okay since your questions are clear and well explained, but if you have more complex questions in the future you will be more likely to get useful answers by following those guidelines.
For your first question, it looks like you want the of primitive- check out the dictionary entry for details. of can be used in a few ways, including allowing agents to check the value of a variable (such as color) of another agent. Check out this example code:
to setup
ca
reset-ticks
crt 10 [
setxy random 30 - 15 random 30 - 15
create-link-with one-of other turtles
]
end
to go
ask turtles [
set color [color] of one-of link-neighbors
]
end
Every time the go procedure is called, one of the turtles changes its color to the color of one of its link-neighbors. If you run it long enough, all connected turtles should end up with the same color.
For your second question, I suggest you check out the Nw extension, which is an extension built to deal more easily with Netlogo networks. Specifically, have a look at nw:turtles-in-radius, which should work with your slider approach. To get it working, include the extension using
extensions [ nw ]
at the start of your code. Then, assuming the same setup as above, you can play around with something like
to network-radius
ask one-of turtles [
set color red
ask other nw:turtles-in-radius 2 [
set color white
]
]
end
When you call the network-radius procedure above, you should see one turtle turn red, and any turtles within 2 links of that turtle turn white. To switch to a slider, just swap the "2" out for your slider variable. Hope that helps!

How to dynamically output value in netlogo

I have created a model in which turtles are born and die based on certain parameters. But at any given point, lets say no more than 20 turtles are alive.
With the birth and death of each new turtle, the turtle label keeps increasing incrementally i.e. initially there are 5 turtles, the 3rd turtle dies and in the next tick a new turtle is born. The new turtle born has a label of 6 and thus old labels are retired and replaced with the next label.
If i want to output a metric associated with the turtles into the monitor, is there a way to dynamically ensure that. i.e. since there can't be more than 20 turtles at any tick, can i make netlogo display the turtle metric along with the turtle label automatically. Otherwise i will have to create 100's of monitors and then code with [metric] or turtle 0.....[metric] of turtle n which is not practical.
If you really want a separate monitor for each turtle, you can do something like this:
Using [ metric ] of item 0 sort turtles instead of [ metric ] of turtle 0 (and so on) will insure that you're not depending on the who numbers of the turtles, you're only depending on their position in the sorted list of turtles.
Note that this would be very inefficient, because each monitor would keep re-sorting the turtles over and over again.
That being said, I think there would be many different, better ways to approach this. Here is one fully working example:
turtles-own [ metric ]
to setup
clear-all
create-turtles 20 [ set metric random 10 ]
reset-ticks
end
to go
ask n-of 5 turtles [ die ]
create-turtles 5 [ set metric random 10 ]
tick
end
to-report info [ the-turtle ]
; format this however you want:
report [ (word who ": " metric ", ") ] of the-turtle
end
And then, in a monitor, put:
map info sort turtles
Which will give you something like:
If map is obscure to you, you may want to check its dictionary entry. The basic idea is that we build a new list of strings by applying the info reporter to each element of our list of turtles.
I used a monitor in the example because that's what you were talking about in your question, but for displaying information about multiple turtles like this, maybe a plot or the output widget would be more appropriate. In any case, you could use a similar approach, with either map or foreach.
One word of advice in closing. Your question shows that you're probably aware of that already, but any time you're tempted to refer to turtles by their who number (i.e., turtle 0, turtle 1, turtle 27, etc.), it probably means you're on the wrong track. NetLogo is built to manipulate agentsets and lists; take advantage of that. And when you do need to refer to a particular turtle, use a reference to that turtle (e.g., the-turtle in the example above), never (or almost never) its who number.

Efficient access to a Turtle's variable which is a patch address, or How to filter patches that are not assigned to turtles?

In my simulation each turtle has a my-home variable which is the patch agent family lives in, so agents with same Family-ID have same my-home until one of agents moves out or family grows to more than 7 agents.
when an agent wants to move out , I have to check if there is any patch nearby which is not another's agent my-home, what I have done is to store all my-homes in a list and check if any selected possible next home is not a member of this list, but I believe there should be better way to do this:
let all-homes [my-home] of agents with [belongs_to = BS]
set my-home min-one-of patches with [not member? self all-homes and label_ = BS][distance m]
m is current home address
min-one-of patches with ... assesses every patch in the entire world before picking a winner. That's going to be slow. I'd suggest searching nearby patches first, then farther patches, and so forth. Most of the time the turtle will find a new home after only a very brief search, so you'll have replaced code that's O(n) in the number of patches with code that's O(1)-ish. That should fix the main performance problem with this code.
The simplest such search routine I can think of is for the turtle to simply head in a random direction and keep moving fd 1 until it lands on a free patch. But if you want to do something more rigorous that always results in finding the closest possible new home, you could do that too; you'll just have more code to write.
Building the all-homes list is probably only a secondary performance problem here, but it's fixable too. The simplest fix I can think of is to add:
patches-own [home?]
initialize it with ask patches [ set home? false ], and then make sure that whenever a turtle adopts a patch as its home, it does ask my-home [ set home? true ]. Now you can replace member? self all-homes with simply home?. After all, you don't really need to know what all of the home patches are; you only need to know whether some particular patch is a home patch.