netlogo mutually exclusive agentsets simultaneously - netlogo

I have 300 workers, and want to divide them into 3 sets of 100 (for now, eventually I will divide them perhaps unequally) based on two rankings. I have written variations to accomplish the following:
Select the top 100 on X, assign value 1 to variable A. Select the too 100 on Y (who have not ALREADY been assigned value 1 on A) and assign value 2 to variable A. Select remainder and assign value 3 to A
I have tried about a dozen approaches, without success. The closest I have come is to get the first 100. BUT, as there are ties, there are a few workers tied at the 100th-rank on X. Netlogo randomly selects one to receive value 1 on Variable A, which is fine. The problem is, because I haven't been able to figure out how to simultaneously construct three mutually exclusive agentsets using 2 criteria, I end up re-assigning workers from value 1 to value 2 on A. I can fix it by hand now, but eventually that won't be possible.
Here's the code that made the first value assignment:
ask max-n-of 100 workers [LPAdv] [set AWeight 1]
The problem seems to be that I cannot figure a way to reference the top 100 on Y of the remaining 200. Nor can I reference the bottom 100 of the remaining 200, because it is possible for a worker to be in the Top 100 on X but NOT in the Top 100 on Y, in which case they'll (wrongly) fall into the sequentially-identified agentset unless I delete them from the operation. I've tried using member? and man other possibilities. Basically, I don't know how to simultaneously dump the first 100 of 300 and only "sort" the remaining 200 to make the assignment.
I've looked at multiple sources for an answer, so far to no avail. I've made a lot of progress on my code since Saturday, but this is a stumbling block.
Any assistance is greatly appreciated!
Thanks!
SLuke

RESOLVED! (YAY!)
In case anyone else has the problem, what I did is the following:
ask max-n-of 100 workers [LPAdv] [set AWeight 1]
ask workers [ifelse AWeight = 1 [set LPMid2 -1000] [set LPMid2 LPMid]]
ask max-n-of 100 workers [LPMid2] [set MWeight 1]
ask workers [set PreWeight ( AWeight + MWeight )]
ask workers [if PreWeight = 0 [set RWeight 1]]
Note that LPMid2 sets the AWeight=1 to -1000, which is way out of range for the actual LPMid variable I later will need.
Sorry to bother the list; I hope the answer is of use to someone else should they have a similar problem.

here's a perhaps easier to read and more scaleable version (untested) of some of your code to hopefully give you some ideas about how to exclude some turtles when you are trying to select from a subset.
ask max-n-of 100 workers [LPAdv] [set AWeight 1]
ask max-n-of 100 workers with [AWeight != 1] [LPMid2] [set MWeight 2]
Also, you don't need two ask statements at the and (and asking twice is less efficient):
ask workers
[ set PreWeight ( AWeight + MWeight )
if PreWeight = 0 [set RWeight 1]
]

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

netlogo: Minimum patch coordinate unit and monitoring availability?

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

How to change a turtle's attribute if one of its links disappear?

In NetLogo: suppose the model has
a turtle (0) of breed A with undirected links with 3 turtles (1, 2 and 3) of breed B;
the turtle 0 has an attribute named "number-of-links" that equals 3.
Now, let one of the 3 neighbors of 0 dies..
How can I program turtle 0 to change its number-of-links automatically to 2?
If all you want is a way of keeping track of the number links, use count my-links instead of a custom variable.
In general, the least bug prone way of having a value update when the number of links changes is to compute that value when you need it. For number of links, this is simply count my-links. For more complicated things, wrap them in a reporter:
to-report energy-of-neighbors
report sum [ energy ] of link-neighbors
end
If this doesn't work for whatever reason (agents need to react to a link disappearing or you're seeing a serious, measurable performance hit from calculating on the fly), you'll have to make the updates yourself when the number of links change. The best way to do this is to encapsulate the behavior in a command:
to update-on-link-change [ link-being-removed ] ;; turtle procedure
; update stuff
end
and then encapsulate the things that can cause the number of links to change (such as turtle death) in commands as well:
to linked-agent-death ;; turtle procedure
ask links [
ask other-end [ update-on-link-change myself ]
]
die
end

NetLogo - compare single agent against many agents (expected input not list)

I am first time poster, six month reader. I love this site and am grateful for the vast array of topics covered. Now that I am feeling a bit more competent using NetLogo, I've tried some harder stuff and got stuck...
Basically, I have created a membership function which measures agents against one another on a vector containing two variables (opinions on rock and hip-hop):
to-report membership [ agent1 agent2 ]
let w 0.5
let w2 sq w
report exp (- d2 agent1 agent2 / w2)
end
where
;;;;;;;;;;;;;;Shortcut functions;;;;;;;;;;;;;;;;;;;;;;;;;;;
to-report d2 [agent1 agent2 ]
report ( (sq ([rock] of agent1 - [rock] of agent2)) + (sq ([hip-hop] of agent1 - [hip-hop] of agent2)) )
end
to-report sq [ x ]
report x * x
end
This all works fine, and I am able to compare any two agents without problem.
However, my trouble arises when I try to compare a single agent [agent1] with all of the agents within his neighbourhood.
to go
ask turtles [
let neighbours turtle-set turtles in-radius neighbourhood
show membership self neighbours]
end
Whenever I run this model I receive an error that the d2 reporter expected an input not a list - which I theoretically understand - by having a neighbourhood of 1+ agent(s), the calculation is receiving for example [0.1 0.8] [0.2 0.4] [0.5 0.6]..............
I was just wondering, is there any way that the procedure can consider all of the neighbours and arrive at one single membership number? I have searched extensively through posts and a couple of netlogo books I have, but no luck so far. Thank you for taking the time to read this post and for any helpful comments.
Your understanding of what is happening is correct: your membership reporter expects two individual agents and you are passing it an agent and an agentset. To calculate each membership individually, and get back a list of membership values, you can use of:
to go
ask turtles [
let neighbours turtle-set turtles in-radius 10
show [ membership myself self ] of neighbours
]
end
Notice the use of myself and self, which can sometimes be tricky to understand. In this case, self is the neighbour and myself is the outer asking turtle.
So now you have a list of membership numbers, but you wonder:
is there any way that the procedure can consider all of the neighbours and arrive at one single membership number?
There are plenty of ways! But we can't really tell you which one to use: it depends on your model and what you want to do with it.
If you wanted something very straightforward, you could just take the mean of the list:
show mean [ membership myself self ] of neighbours
...but I don't know if it makes sense in your context. In any case, NetLogo has plenty of
mathematical primitives that you should be able to use to arrive at the number you want.