Reputation: 327
I'm very new to netlogo and was working on "Follower" model. In extending the model propositions there is a "what if two turtles are allowed to have the same leader?" I was wondering if there is a way to count the number of followers in turtles (something like
count follower
and then use it in a way like :
let candidate one-of (turtles-at xd yd) with [follower = nobody or count follower < 2]
which gives this error on runtime:
COUNT expected input to be an agentset but got the turtle (turtle xxxx) instead.
I solved the problem with a hack (adding a new variable f-num and then incrementing it when a new turtle is attached to the current turtle, and selecting candidates with the condition f-num < 2) but wanted to know if there is a better way for such a problem
Upvotes: 2
Views: 160
Reputation: 2926
The problem is that the original statement for setting follower
is
ask candidate [set follower myself]
and myself
is not an agentset, is an agent. This means that, unless that statement changes, follower
is never going to be something countable: you can count how many agents are there in an agentset (which could also be an agentset of 1 or of 0), but you cannot count an agent.
The solution then has to be to change that statement, initialising follower
as a different object - one that accommodates multiplicity (which means one on which you can perform an addition and one that you can measure).
As I said, agentsets can be counted. Actually, agentsets are the natural type of object that count
operates on. Therefore, we could initialise follower
as an agentset.
A way to do it is by using turtle-set:
...
ask candidate [set follower (turtle-set follower myself)]
...
In that case, for consistency I would also change the create-turtles population
bit by doing:
...
set follower (turtle-set)
...
This way, follower
will be an agentset for all turtles since the beginning (starting as an empty agentset instead than as nobody
).
I would much prefer it for consistency, but pay attention that this means that all the conditions asking whether follower = nobody
don't make sense anymore: an empty agentset is different from nobody
!
In fact, if you just make the above change, then click on setup
and then run count turtles with [follower = nobody]
in the Command Center, you would get 0.
Running instead count turtles with [count follower = 0]
you would get all the turtles.
So the conditions with nobody
will have to be changed accordingly; and, in particular, the one that was the object of your question will become a tidy
...
let candidate one-of (turtles-at xd yd) with [count follower < 2]
...
So, to bring back a bit of tidiness, let me put these three changes in their in-code logical order:
; The initial declaration when you create turtles:
...
set follower (turtle-set)
...
; The condition where you test how many followers a turtle has:
...
let candidate one-of (turtles-at xd yd) with [count follower < 2]
...
; The action of adding a follower:
...
ask candidate [set follower (turtle-set follower myself)]
...
; Plus changing other instances where the original code says 'with [follower = nobody]'.
NOTE
As you saw from the description of turtle-set
, it is a very flexible primitive: basically it turns anything into an (turtle) agentset.
The most common way to create agentsets on the go, however, is using with
. The logic is that a subgroup of an agentset is still an agentset; given that with
can only be used on agentsets, what it gives you back can only be an agentset.
In our case, however, using with
would have not been that tidy/simple.
The follower
variable could have been initialised as an agentset quite easily using with
:
ask candidate [set follower turtles with [who = [who] of myself]]
However, this only command would have set follower
each time as the agentset containing the only turtle with that specific who
, thus not helping with the intention of incrementing the numerosity of the agentset.
This is when things would have started to become more convoluted than just using turtle-set
.
Another type of object that can be counted are lists. As you can imagine, you don't count lists with count
but you can do it with length
.
In this case, we just initialise follower
as a list, add agents as items to the list using lput
or fput
(depending on how one wants to use the list), count the length of the list when checking the condition.
Changes mirror the ones we made in the agentset solution:
; The initial declaration when you create turtles:
...
set follower (list) ; or
set follower []
...
; The condition where you test how many followers a turtle has:
...
let candidate one-of (turtles-at xd yd) with [length follower < 2]
...
; The action of adding a follower:
...
ask candidate [set follower (lput myself follower)]
...
; Plus changing other instances where the original code says 'with [follower = nobody]'.
Using a list will be useful if you want to keep track of the order of turtles following the leader. In fact, while lists are ordered objects, agentsets are unordered (literally agents in an agentset come/act in a random order everytime you call that agentset).
Upvotes: 3