I'm trying to implement a monitor in the user interface that displays the average value of a variable shared by a breed of turtles (turtles own). Does anyone know of a method of collecting all the values, adding them together and dividing by the quantity of turtles to get the value or know of an easier method?
If the variable that each turtle has is shell-size, for example, then:
print mean [shell-size] of turtles
will do it. It might be useful to know how to do this by hand, so that you can do other calculations if you want. Here's one way:
print (sum [shell-size] of turtles) / (count turtles)
Here's another
let total 0
ask turtles [set total total + shell-size]
print total / (count turtles)
Obviously, you'll want to replace the print statements with whatever suits your needs. For a monitor, you should be able to enter this code directly into the interface, or wrap it up in reporter and then use that in the monitor.
Related
Looking for a way to store a turtle length of stay in the model after they have left the model. My model runs for several months and a few thousand turtles enter, undergo process then leave the area. It's complicate model (it's a hybrid DES and ABM) so I've tried to reproduce the simple bit below.
Turtles will be created at every tick and given a random length of stay but will only be able to begin process when they move to the right area (area-name) and when their time is up they leave the area. Their time-in-system reflects the wait for the area and the length-of-stay which I want to save once they're complete. If I leave them in the model it starts to break down after a couple of months and I suspect this is because the model has too many turtles still in the system for calculation and is inefficient.
go
create turtles 2
[
set time-in-system 0
set length-of-stay ceiling ((random-normal 48 4) + ticks)]
set shape "person"
if any? area-name with [not any? turtles-here]
[move-to one-of area-name]
]
undergo-process
end
to-undergo-process
ask turtles with [shape = "person"]
[
set time-in-system time-in-system + 1
]
ask turtles-on area-name
[if ticks = length-of-stay
[set shape "dot"
move-to exit-door]
end
I can then plot and see in realtime to make sure it is working
histogram time-in-system of turtles with [shape = "dot"]
but can't seem to figure out how to store them as unique values for plotting after the model has run and I have a dataset of outcomes without keeping them alive in the model. The real-time plot isn't necessary as long as I can store the unique values after they have left
If I ask them to die then I lose the unique values in the histogram. I don't want a tally of all values but each turtle's unique value at the end of the process after they left - at the moment the only solution I have to storing them is as an agent-set that stays alive in the exit-door patch but this takes up a lot of calculation power as the model progresses for months...
There may be a really simple command for this but I've been going round in circles through the programming manual trying to find it. Any tips appreciated
You should create a list storing the values of turtles that left.
Isolating only the code that is relevant for this purpose, it would be something like:
globals [
times
]
to setup
set times (list)
end
to leave-simulation ; This being executed by turtles.
set times lput (time-in-system times)
die
end
If your program is going to run for actual months, I recommend you use the file-write command to store your data. This way the data is preserved if the program halts for any reason; it gives you much more freedom to do the analysis you want without running the full simulation again.
If you write to a .csv (comma separated value) file, you can use almost any program (excel, R, matlab, python, C# or back to netlogo) to plot a histogram.
I'm new to Netlogo and I'm now stuck with coding this sentence:
There should be a chance of 10% divided by the total number of turtles that a turtle will hatch a child.
The initial total number of turtles is 1.
So my code is:
let p (0.1 / 1)
ask n-of (0.1 / 1) turtles
[hatch 1]
But it seems to me that my code may not be correct. Anyone any ideas how to change it?
I would appreciate any kinds of help. Many thanks in advance!
"ask n-of" is clearly wrong, if there's only one turtle. And the random function only returns integers, so instead of checking for 0.1, let's choose a random number from 0 to 10 times the number of turtles. Something like this should work.
if random 10 < 1 [
ask one-of turtles
[hatch 1]
]
Here's my justification. Any given turtle has a 10%/N chance of hatching. That means that, 10% of the time, one random turtle has a 100% chance.
Say there are 5 turtles. By the spec, each turtle has a 2% chance of hatching (10%/5). 90% of the time, no one hatches. In the remaining 10% of the cases, 1 of the 5 will definitely get a chance. That means each individual turtle's chances are 10% x 20% which is 2%, as the spec says.
That's what the code does. "random 10" chooses a random number from 0 to 9. If that number is "< 1" (which means 0), then we choose a turtle at random to hatch.
How about this, put the random chance inside the ask
ask turtles
[ if random-float 1 < 0.1
[ hatch 1
]
]
Part of the problem is that the question is badly expressed. "10% divided by the total number of turtles" doesn't really make sense, so I have interpreted it that approximately 10% of the turtles hatch a child turtle
I'm writing a program that is testing the ability of turtles to navigate in an environment. This line of code has two checks. I want it to kill off the oldest turtle that has made the least amount of progress. It does what it is supposed to, but the program slows down dramatically, creating little hiccups every time it makes this check. I was wondering if someone knew a better way to go about this or make this line more efficient. Thanks!
ask one-of turtles with [XCOR = min [XCOR] of turtles with [age = max [age] of turtles]] [
die]
First of all, there are primitives that are specifically finding the turtles with maximum or minimum values of some variable using min-one-of or with-min. So your code would look something like this I think:
ask min-one-of (turtles with-max [age]) [xcor] [...]
I suspect that would solve your efficiency problem, since it may well be because of implicit brackets not being where you think they are so it's trying to loop everything a couple of times. But a much cleaner to read version that would solve the efficiency problem is to specifically limit the position loop to those who are oldest and then choose the lowest position from that set.
let old-turtles turtles with-max [age]
ask min-one-of old-turtles [xcor] [...]
I've made a population model in Netlogo where the simulation stops when all my turtles have died OR the number of 300 ticks is reached. I need to report (or write to a file) the mean state of my turtles (turtle-own variables) one tick before the simulation ends. It would be easy if all simulations will run to 300 ticks, but in most cases the simulation ends before this happens (all turtles die). How can I achieve this? The death of the turtles is conditioned to either their "lifetime" runs out or to a stochastic probability of dying, so I can't predict when will this happen, and I need to know whether the last turtle died due to their lifetime running out or due to the probability worked against the turtle. Thanks!
Have you played around with BehaviorSpace at all? It works pretty well for means and sums etc. You can easily make BehaviorSpace experiments to export whatever reporters you set up to a .csv spreadsheet or table, whether you want reports at the end of your simulation or at each tick. For a simple example, if I want to know the mean x-coordinate of my turtles, I can set up the reporter using to-report:
to-report mean-xcor
let xlist ( [xcor] of turtles )
report mean xlist
end
Then, I can use Behavior Space (Tools > Behaviour Space) to set up an experiment that writes that mean xcor for all turtles at either each tick or only at the end of a run. The tool also allows you to set up multiple parameterizations of your simulation and compare results with different treatments- it's really handy! You can get creative with what you report in order to have the output be what you need. For your specific case, you could just make sure that your experiment is recorded at each tick.
You could also do this manually and with a little more control if you prefer. You can create a file and header during your setup using something like:
to setup-turtle-reporting
file-open "turtle_details_out.csv"
file-type (word "tick, who, xcor, ycor \n")
file-close
end
That sets up a .csv file in your model folder that has the column headers tick, who, xcor, and ycor. Then, during each tick you can have turtles write the appropriate variables to that same file:
to turtle-report
file-open "turtle_details_out.csv"
ask turtles [
file-type (word ticks ", " who ", " xcor ", " ycor "\n" )
]
file-close
end
This option gives you a bit more control in some ways, but is fiddlier. You will have to also play around with file-delete or manually delete/rename the file as you complete different simulations, as file-type will append to the existing file rather than overwriting it.
I am building a type of 'honey-bee' model, where the bees are turtle agents and the honey is a patch specific variable. In my model, each patch is assigned a value of 'honey-here' between 1-100 based on a specific distribution.
The model starts with the bees only being able to collect honey from flowers with honey = 1, for which they then receive 1 unit of honey in return. Before the bees can 'target' flowers with honey = 2, they need to occupy (i.e. a bee on a flower) X% of the total flowers with honey = 1. For example, I might require the bees to achieve 80% occupancy, which means if there are 10 flowers total with the variable honey = 1 then the bees need to occupy 8 of those flowers before they are allowed to start looking/targeting flowers with honey = 2. As each bee individually acts, the % occupancy value will change.
I'm having performance issues for the occupancy calculation. Ideally the calculation is updated within a turtle procedure as it needs to be applied to each turtle within the loop. Here's what I currently have to find the value of the variables I need to set current % occupancy before each bee is allowed to act:
ask bees
[
;; set up variable based on ratio of number of turtles occupying target patch size against total number target patch size
;; note -- don't do this in one step to avoid divide by 0
let patch-count-current (count patches with [honey-here = bee-honey-target-size])
;; don't want number of bees, want number of unique patches
let patch-target-occupy count patches with [ (count bees-here > 0) and (honey-here = bee-honey-target-size) ]
...
Later in the code, after checking to make sure patch-count-current isn't 0, I find my % occupancy via patch-target-occupy / patch-count-current
It turns out this is a very expensive hit on my processor performance. Especially as my number of bees grows, which is exponential in my model.
Is there a better way that won't cost me so much processor for each iteration of the loop?
Thanks!
-dp
Given your response to StephenGuerin, you could manually track the counts with global variables. If there is only one bee-honey-target-size at a time, this is pretty simple. Just make a patch-count-current global and a patch-target-occupy. Then, increase them or decrease them as things change.
The Sandpile model (from the models library) uses this technique to keep track of the total amount of sand without having to iterate over the patches. Check out how the total global variable is used.
If you need to keep track of the counts for all bee-honey-target-sizes at once, you could store a list of the counts in a global variable, where the index of the list corresponds to a value of bee-honey-target-size. This is much messier unfortunately, so you would have to write helper functions for sure.
Let me know if any of this needs clarification.
Percentage occupancy is a property of the group and only needs to be calculated once per simulation step. Your performance hit is due to calculating occupancy for every bee in your simulation. The calculation for percentage occupancy for a given 'target-honey' could look like this:
to-report calc-occupancy [target-honey]
report (sum [count turtles-here] of patches with [honey-here = target-honey]) / count turtles
end