Setting specific patch identifier - netlogo

I want to have specific 'who' (labels) of the patches.I have attached a picture for it. How can I set it? Is it setting manual 'who' of patch numbers? or Is there any other way of doing it?
Thanks
picture for patch identifiers

If you don't care about the specific "spiral" sequence in your example, you can use a variant of Luck's solution that takes advantage of NetLogo's default patch sort order:
patches-own [ id ]
to setup
clear-all
(foreach (sort patches) (range count patches) [ [p n] ->
ask p [ set id n ]
])
ask patches [ set plabel id ]
end
Or you could use a slightly different sort order specified with sort-by.
That being said, I don't know what your requirements are, but I would question the idea of having a specific id for patches. Most things in NetLogo can be done without ever refering to an agent's id. The who number itself is a relic of very old NetLogo versions and should almost never be used in modern code.
If you want to refer to a specific patch, refer to it by its coordinates, for example: patch -2 4.
If you want to store a patch for future reference, store a reference to the patch itself, not some kind of id. For example: ask turtles [ set my-patch one-of patches ].

A patch doesn't have a who since that is a turtle-only variable; patches have coordinates instead. However, you could give patches their own id number and use that. If all you need is a 5 x 5 world (as in your picture), you could accomplish what you want in Netlogo code. For example, see the code below (and note that I changed the world settings to those seen here). However, if you want a world with more patches, I would recommend reading your desired patch values from a file.
globals [
idlist
ordered_patches
]
patches-own [
id
]
to setup
set idlist [ 9 10 11 12 13 24 1 2 3 14 23 8 0 4 15 22 7 6 5 16 21 20 19 18 17 ]
set ordered_patches sort patches
end
to assign-ids
( foreach ordered_patches idlist [
[ o_patch _id ] ->
ask o_patch [
set id _id
]
]
)
ask patches [
set plabel id
]
end

Related

Introducing IDs to patches in Netlogo

I am working on a model which is supposed to act like a human tissue. It is composed of only patches which represent the human cells. The cells replicate over time, and I want to introduce unique IDs to each of the individual patches (cells). These IDs should also carry over to the daughter cells after the replication. I cannot seem to find a good starting point for this and not sure how to approach it.
This is the code I tried but it is not working to even at least give each patch a unique ID. Track clones is supposed to give each of the patches an ID and I will later introduce more to the code to track individual patches and their division over time.
to track-clones
; let patch-list patches
; let patch-count count patches
; foreach patch-list [
; set id ?1
; ]
end
This will have each patch take unique and sequential IDs:
to assign-ids
ask patches [
set id (max [id] of patches + 1)
]
end
That said, it is not clear to me what you mean, in model's terms, when you say
These IDs should also carry over to the daughter cells after the replication.
given that we don't know how such replication is supposed to take place - but it seems this is a separate issue to address.
PS: the syntax using ? for anonymous procedures is no longer accepted, make sure to check the latest NetLogo Dictionary.
You can quickly assign an initial ID based on the patch coordinates
Ask patches [ set patch-id (pxcor - min-pxcor ) + (pycor - min-pxcor) * world-width
]
Alternately, you can use the patch itself as the patch ID:
Ask patches [ set patch-id self ]
This might make other operations relating to the progenitor patch simpler.

How to report agent variables in a consistent order in Netlogo's Behaviourspace

Picture of my behaviourspace menu
I'm working on an agent based model where a variable (agentvariable1) owned by all agents changes every tick. I want to report a time series for the values of this variable for every agent using Behaviourspace.
However, when I measure runs using the following reporter
[agentvariable1] of turtles
the values that are reported for agentvariable1 are randomly shuffled, because "turtles" calls all turtles in a random order, which is different every tick. Because of this the data that is exported is not usable to create a time-series.
Is it posstible to create a reporter in Behaviourspace that reports the values of the agentvariable1 in a sequence that remains the same every tick?
Using sort on an agentset creates a list of those agents sorting them by some criteria. In the case of turtles, they are sorted by their who which means that their relative order will always be the same.
However you cannot directly do [agentvariable1] of sort turtles, because of expects an agent/agentset but you are giving it a list.
What you can do is creating a global variable as a list: at each tick the list is emptied, and later all turtles (sorted as per sort) will append their value to the list.
That list is what you will report in your Behavior Space.
globals [
all-values
]
turtles-own [
my-value
]
to setup
clear-all
reset-ticks
create-turtles 5
end
to go
set all-values (list)
ask turtles [
set my-value random 10
]
foreach sort turtles [
t ->
ask t [
set all-values lput my-value all-values
]
]
show all-values
tick
end
As an alternative to Matteo's answer (which is perfectly suitable and directly addresses your intention, I just present another option depending on preference) you could also pair the variable of interest with some turtle identifier and report that as a list of lists. This adds a bit of flexibility in cases where the number of turtles increases or decreases. In this example, I use who and xcor for simplicity, but you may want to create your own unique turtle identifier for more explicit tracking. With this toy model:
to setup
ca
crt 5
reset-ticks
end
to go
ask turtles [
rt random 30 - 15
fd 1
]
tick
end
to-report report-who-x
report list who xcor
end
At any point, you can call the list with [report-who-x] of turtles to get a list of lists. With a behaviorspace setup such as:
you get an output that would look something like:

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).

Netlogo: asking "up to a maximum number"

Is there a way to ask up to a certain number of patches? For example, ask up to 100 patches but there are only 50 available, so the action takes on this 50 patches. Thanks.
The way to do this at the moment would be something like:
to-report at-most [n agents]
report ifelse-value (n <= count agents) [ agents ] [ n-of n agents ]
end
You can then say ask at-most 100 patches [ ... ] and you will get what you want.
Note that this doesn't work if there is a chance that your variable contains nobody instead of an agentset. In that case, you can convert nobody to an agentset using patch-set, turtle-set or link-set, depending on the type of agent you expect it to contain. For example:
ask one-of turtle-set other turtles-here [ ... ]
Note that the need to jump through all these hoops might disappear in the near future. There is currently an open proposal to add a primitive to NetLogo for handling these cases: https://github.com/NetLogo/NetLogo/issues/1594.

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.