netlogo: Minimum patch coordinate unit and monitoring availability? - coordinates

I would like to change the minimum coordinate unit of the patch space, which is set to exist only one turtle per patch space, to less than one, and monitor it. We want to set the minimum spatial unit to the same tick size n as in tick-advance (e.g. n=0.1). Here is a piece of code, but it doesn't work. Can anyone help me? Thanks in advance.
globals [n] ; n<=1 i.e. n=0.1
; omitted
ask turtles [forward n]
tick-advance n

I find myself in the same boat as Matteo- I don't know that what you're looking to do is possible / makes sense in the context of NetLogo. The coordinates of patches are fixed (ie, one patch is one unit) but arbitrary (1 in Netlogo can mean 1 m or 1 km, depending on the model). In other words, a patch's coordinates are discrete, while turtles can move around in continuous space. So you can, of course, have a turtle wander around in step sizes of 1/10:
globals [n]
to setup
ca
set n 0.1
crt 10
reset-ticks
end
to go
ask turtles [
forward n
]
tick-advance n
end
After one run of go above, you could conceivably have a turtle at coordinates [xcor = 0.1, ycor = 0.1], although it would still be on patch 0 0 since pxcor values are integers.
It seems that what you are actually needing to do is not coming across as needed- can you edit your question to provide a little more detail / context? Perhaps knowing the why behind your need to model in this way will help askers get you pointed in the right direction. I personally am curious about:
Why you are using tick-advance instead of just tick
How you have implemented your one-turtle-per-patch restrictions- in other words, can you show a Minimal Reproducible Example? That may prompt other ways to approach what you're after.
Here is an example world with time tied to ticks:
globals [ seconds ]
to setup
ca
set seconds 0
resize-world 0 50 0 50
ask patches with [
floor (pxcor / 10) mod 2 + floor (pycor / 10) mod 2 = 1
] [
set pcolor white
]
crt 10
reset-ticks
end
to go
ask turtles [
fd 1
]
set seconds precision (seconds + 0.1) 2
if seconds mod 1 = 0 [print ( word "It has been " seconds " seconds.")]
tick
end

Related

How to optimize assignation process in Netlogo

I want place 1 million fish in a lake at random to do so i have this.
ask patches[ if sum [peces] of patches < 1000000 [ask one-of patches with [mallor = 1][set peces peces + 1]]]
This is taking too long, how would you suggest to make it quicker? I know it´s the sum part as it has to always check, but i dont know how else to do it
A first thing I noticed is that you have the construction:
ask patches [ if ... [ ask one-of patches [...]]]
That first ask patches is completely redundant here. It lets each patch direct another random patch to make a fish. Since you use one-of the second time around I don't expect that the speed impact is too big but it should still help
Next, I suggest counting the fish you have already placed with a single local variable, instead of using sum [peces] of patches 1000000 times. Getting variables from an agent (with of or with) takes a lot of time if you have a lot of agents, and I remember from your previous questions that your number of patches is pretty huge.
Then thirdly, you also check for which patches the mallor = 1 condition is true 1000000 times. That one can also be grouped into a local agentset
let fish-placed 0
let mallor_patches patches with [mallor = 1 ]
while [fish-placed < 1000000] [
ask one-of mallor_patches [
set peces peces + 1
set fish-placed fish-placed + 1
]
]
Disclaimer, I haven't tested any of this code in Netlogo since I don't have the bigger model to test the code in. However I expect it will run a many times faster than what you originally wrote.

Percentage in netlogo

I want to write in Netlogo that a certain percentage of the agent's population has this attribute. How do I do that in NetLogo?
So far, in a toy model, I do it manually. i.e: ask n-of 740 households [set composition 1] when in fact I want to say: ask 8% of the households to set composition 1.
There are two ways. I will call them ex-ante and ex-post.
Ex-ante
A frequent approach is to let each agent have a certain chance (expressed as the percentage value) of doing something. In this case you will use the random-float command in combination with your percentage value, which is the standard way to make things happen in NetLogo according to a certain probability (see here, or also see just random if you're working with integers). It can be used directly within the create-turtles block of commands:
globals [
the-percentage
]
turtles-own [
my-attribute
]
to setup
clear-all
set the-percentage 0.083 ; In this example we set the percentage to be 8.3%.
create-turtles 500 [
if (random-float 1 < the-percentage) [
set attribute 1
]
]
end
This means that you will not always have the exact number of turtles having that attribute. If you check count turtles with [attribute = 1] on multiple iterations, you will see that the number varies. This approach is good if you want to reproduce the probability of something happening (over a population of agents or over time), which is the case for many uses of NetLogo models.
Ex-post
The ex-post approach follows the logic that you more or less expressed: first you create a number of turtles, later you assign to them the attribute. In this case, you simply need to treat the percentage as in any other mathematical expression: multiply it by the total number of turtles to get the relevant turtles:
globals [
the-percentage
]
turtles-own [
my-attribute
]
to setup
clear-all
set the-percentage 0.083
create-turtles 500
ask n-of (count turtles * the-percentage) turtles [
set attribute 1
]
end
With this approach, you will always have the exact same number of turtles with that attribute. In fact, if you run count turtles with [attribute = 1] on multiple iterations you'll see that the result is always 41 (500 * 0.083 = 41.5, in fact if the number passed to n-of is fractional, it will be rounded down).

Set energy to go down as my turtle breeds begin moving faster and set a limit to how large a turtle can grow

Currently the sharks and fish continue growing in size and speed what I'm attempting to do is have the energy for the fish and sharks go down more as they continue to move faster as as demonstrated with forward energy over 7 I'm also attempting to set a limit on the size the sharks and fish can reach
To go
update-plots
tick
ask sharks[
set Btimer (Btimer - 1)
forward Energy / 7
right random 80
left random 80
ask fishes[die]
set Energy (Energy + 7) ;this essentially controls speed making it so it will go faster if enough energy is collected
set size size + 0.1 ; this makes it so the sharks will continue growing and I'm not sure how to set a limit to the size they can grow to be
]
set Energy (Energy - 1)
if (Energy <= 0)[
die
]
if any? sharks-on patch-ahead 0 and Btimer <= 0[
ask sharks-on patch-ahead 0 [
set Btimer (Btimer + 400 - random 200)
set Energy (Energy - 50)
]
hatch 10 [
]
]
]
end
The basic problem appears to be that you increase speed every tick but don't have any code to stop growth. Here is one way to do it - you just have a test to see if the shark is fully grown:
to go
update-plots
tick
ask sharks
[ set Btimer (Btimer - 1)
forward Energy / 7
right random 80
left random 80
ask fishes [ die ]
if energy <= max-energy ; here is where you set the condition
[ set Energy (Energy + 7) ; also increases speed
set size size + 0.1
]
]
ask sharks ; There must be an ask here, otherwise error message
[ set Energy (Energy - 1)
if (Energy <= 0) [ die ]
if any? sharks-on patch-ahead 0 and Btimer <= 0
[ ask sharks-on patch-ahead 0
[ set Btimer (Btimer + 400 - random 200)
set Energy (Energy - 50)
]
hatch 10 [ ]
]
]
end
But this is primarily a design issue - what are you trying to represent with stopping the growth? Is it that the shark has become an adult, in which case a condition like the one I have inserted is the right approach.
Or is it that you expect growth to stop naturally for some other reason? For example, you might be thinking that the shark will stop growing because it runs out of food. However, the growth happens whether there is food or not. If you wanted the growth to happen only if there is food (fish) where the shark is, then you would do something like this:
to go
....
ask sharks with [any? fishes-here] ; restrict to sharks with food
[ set Btimer (Btimer - 1)
forward Energy / 7
right random 80
left random 80
ask fishes-here [ die ] ; since they are shark food
set Energy (Energy + 7) ; max not required, grows if food available
set size size + 0.1
]
....
end
Just a general comment, agent-based models are hard to debug because the complex interactions between agents, environment and behaviour means that it is not always clear which bit of the code is causing a problem, and the logic can be difficult. The best way to deal with this is to code in smaller pieces - just add the minimum change and make that work before writing anything else. For example, the way you have the code written, all fishes die immediately. That is a different problem. If you write only one piece at a time, then you only ever have one problem and you know what is causing it.

Update a monitor once per tick instead of continuously. Slow model

I know that monitors are updated several times per second, and that can be helpful when checking the output of a model; however, that is not the case for my model, it just weighing it down.
I am trying to plot data from a monitor. I want the monitor to only update the reporter once per tick, if possible.
My model currently functions but it is bogged down updating multiple times a second. I was hoping someone could help me minimize my model's computational effort by updating once per tick.
sample of current code:
globals [initial-patch0-health patch0-health intial-patch2-health patch2-health]
patches-own [ptype penergy max-penergy alive?]
to setup
clear-all
set patch-health 0
ask-patches [
setup-patches
]
reset-ticks
end
to setup-patches
let temp random 100
if temp <= 50 [
set ptype 2
set max-penergy random-in-range 0 5
set alive? true
]
if temp > 50 and temp <= 75 [
set ptype 0
set max-penergy random 10
set alive? true
]
set penergy max-penergy
set patch2-health (ptype2-health)
set patch0-health (ptype0-health)
end
to go
ask-patches
update-patch-health
tick
end
to patch-health
if ptype = 2[
set patch2-health (ptype2-health)
]
if ptype = 0 [
set patch0-health (ptype0-health)
]
end
to-report ptype2-health
report [penergy] of patches with [ptype = 2]
end
to-report ptype0-health
report [penergy] of patches with [ptype = 0]
end
My monitors and plot read (same for patch2-health):
sum (initial-patch0-health)
and
plot sum (patch0-health)
I use sum in this situation because the reporter delivers a list.
For context, I am doing a simple "sheep-wolf predation" style model but I want to monitor the initial grass health vs grass health over time, with multiple grass types (ptype). I have turtles but did not include that code here. Let me know if you need more code from me.
This code gives me the output I desire just at the cost of speed. I figured only reporting once every tick would save some computing time. Any suggestions for cleaning and speeding it up?
Your code example is not usable to me (undefined variables, patch0-health is not output from a reporter, other errors)- check the MCVE guidelines. With that in mind, I'm having trouble replicating the issue you describe- I ran a few profiler tests with a monitor present and not present, and didn't get any difference in runtime. With this setup:
extensions [ profiler ]
globals [ patch-turtle-sum profiler-results]
to setup
ca
ask n-of ( ( count patches ) / 2 ) patches [
set pcolor red
]
crt 1000 [
setxy random-pxcor random-pycor
]
set profiler-results []
reset-ticks
end
to profile-check
repeat 20 [
profiler:start
repeat 20 [
go
]
set profiler-results lput profiler:inclusive-time "go" profiler-results
profiler:reset
]
print profiler-results
end
to go
ask turtles [
fd 1
]
tick
end
to-report patch-turtle-sum-report
report sum [count turtles-here] of patches with [ pcolor = red ]
end
I ran the profile-check procedure from the interface, once with a monitor that monitors patch-turtle-sum-report present (mean go inclusive time: 678.59 ms) and once without (mean go inclusive time: 678.56 ms)- no detectable difference. However, I'm not sure if profiler accounts for monitor, so maybe that assessment is just not useful in this case. It could also be that the number of patches you're dealing with is quite large (in my test example I was doing 100 X 100 patches) so that the calculations get bogged down.
I wonder if you could get around your issue by using a monitor that just reports a variable that you manually calculate once per tick (instead of a to-report reporter)- eg to follow my example above, monitor a variable that is updated with something like:
set patch-turtle-sum sum [count turtles-here] of patches with [ pcolor = red ]
That way you control when the calculation is done, which may speed up the model if the calculation is what's actually slowing down your model.

Accumulating per-step mortality model procedure in Netlogo

Kindly advise as to what I might be doing wrong in the following netlogo procedure for per-step mortality (I am implementing the "Pass-Away" procedure as a step in a "GO" procedure):
to Pass-Away
ask turtles [
let chances 1 - exp( -1 * mortality * ticks )
let dead-count 0
if chances >= 1 [die]
set dead-count dead-count + 1
]
end
Is the above code correct? Even if it is correct, is there a modified or better alternative means to achieve a constant (cummulative) per-time-step turtle mortality as they move through the world? Finally, how do I get the variable "dead-count" to report to a monitor on the netlogo interface?
This will mostly work, except that your dead-count will always be 1. But it will probably not work as you intend. You should embark on an exploration of what you have written. The first thing to do when you get confused is to break things into smaller pieces. The second thing is to add some helpful visuals. In this case, you will learn a lot by plotting your representation of chances. I'm going to have to guess that your mortality attribute is a random float, since you did not say so. The following is a partial fix of your code, which provides enough clues to continue. You will need to add a plot in the interface tab -- see https://subversion.american.edu/aisaac/notes/netlogo-basics.xhtml#core-concepts-plotting -- and you can add a monitor in the same way if you find monitoring with print too clunky.
globals [dead-count]
turtles-own [mortality]
to setup
ca
set dead-count 0
crt 100 [set mortality random-float 1]
reset-ticks
end
to go
ask turtles [pass-away]
print (word "dead count = " dead-count) ;easiest monitor
clear-plot ;you'll need to have added a plot
foreach sort [chances] of turtles [
[?] -> plot ?
] ;keep an eye on the largest value in this plot ... get it?
tick
end
to-report chances ;turtle proc
report 1 - exp( -1 * mortality * ticks )
end
to pass-Away ;turtle proc
if chances >= 1 [
set dead-count dead-count + 1 ;*inside* the conditional! must come first!
print (word "chances: " chances)
die
]
end