I have turtles linking if they have an equal value for var1 (this works fine). I want to limit the number of links to just three. I added an IF statement before the linking part of the code (If count my-links < 3), but it does not work; the agents continue to link past the max value I set. I read the other question How to limit the number of links an agent can make in a model but that doesn't seem to quite do what I am attempting here. What am I doing wrong?
to communicate
If count my-links < 3
[
ask other xagents in-radius 5 with [var1 = [var1] of myself]
[create-links-with yagents in-radius 5 with [var1 = [var1] of myself]
[
set color white
set thickness 0.1
]
]
]
end
Limit number of links for the turtles before letting them create new ones:
By looking at your complete module, as #JenB mentioned that, it seems that there's no condition to limit number of links that the targeted turtle has for making a link.
This would be the first step:
to communicate
If count my-links < 3
[
ask other xagents in-radius 5 with [(var1 = [var1] of myself) and (count my-links < 3)]
[create-links-with yagents in-radius 5 with [(var1 = [var1] of myself) and (count my-links < 3)]
[
set color white
set thickness 0.1
]
]
]
end
But what if there's no agent like that? (in radius of 5, with the same val1 and links less than 3) Probably an if-statement is needed.
I also think you need to use one-of in your code to make only one link in each step.
Kill links after each tick to limit the number of links for turtles:
You can have this at the end of your communicate sub-procedure to kill the extra links. It has a down-side of random removing links and also may remove the link from turtles with fewer link instead of the ones that may also have extra links.
ask turtles with [count my-links > LIMIT] [ if count my-links > LIMIT [ask n-of (count my-links - LIMIT) my-links [die]] ]
Related
I have a question and couldn't find an answer to it. The question is:
I have a code that exports the following result:
I would like the column (energy-of-my-agent) to be exported without the brackets [], like the figure below.
The code:
globals [ output-filename ]
turtles-own [ energy my-home ]
patches-own [ patch-id my-agent energy-of-my-agent ]
to setup
ca
reset-ticks
set output-filename "energy-of-my-agent.csv"
ask patches [
sprout 1
set patch-id [ who ] of turtles-here
set my-agent turtles-here ]
ask turtles [
set my-home patch-here
set energy 0
]
initialize-data-file
end
to initialize-data-file
if output-data?
[
file-close-all
if behaviorspace-run-number <= 1 [
;; we only want to delete the existing file if we're running in console
;; when running in console, behaviorspace-run-number = 0,
;; first run in behavior space is behaviorspace-run-number = 1
if file-exists? output-filename [
file-delete output-filename
]
;; write a header to the file
file-open output-filename
file-print (word "run-number, ticks, energy-of-my-agent, pxcor, pycor" )
]
]
end
to go
ask turtles [
let times repetitions
repeat times [
let step random 5
fd step
set energy energy - step
]
]
ask patches [
set energy-of-my-agent [ energy ] of my-agent
if output-data? [
if ticks mod output-every-n-ticks = 0 [ ;;output-every-n-ticks
write-output-data energy-of-my-agent pxcor pycor
]
]
]
tick
end
to write-output-data [ #energy-of-my-agent #xpos #ypos ]
file-open output-filename
file-print (word behaviorspace-run-number ", " ticks ", " #energy-of-my-agent ", " #xpos ", " #ypos )
file-flush
end
Is it possible? If so, how can I do this? Any kind of help is very welcome.
Thanks in advance
In NetLogo, square brackets containing items represent a list.
In fact, the energy-of-my-agent variable in your output is in square brackets because it is a list (lists don't have to contain multiple items: empty lists or lists of one item are perfectly possible lists).
Why is energy-of-my-agent a list and not a single value? Because it comes from an agentset and not from an agent (as we already discussed here).
The rule is:
reporter of agent -> single value (unless the value is already a list in itself)
reporter of agentset -> list
In your case: energy-of-my-agent is made by [energy] of my-agent, and my-agent is an agentset, not an agent.
Why so? Because my-agent is made by turtles-here, and turtles-here is an agentset, not an agent, even if it contains one only agent. In the same way as lists, in fact, agentsets don't have to contain multiple agents: empty agentsets or agentsets of one agent are perfectly possible agentsets.
So you have three alternative options:
Use set my-agent one-of turtles-here. This will give you a single agent, because one-of reports a single agent. If you are sure (as it seems to be the case) that patches will always only sprout 1, then one-of turtles-here will give you the exact same agent as turtles-here - but as an agent indeed, and not as an agentset. This in turn means that [energy] of my-agent will be a single value, and not a list of one value.
When outputting values, use sum energy-of-my-agent. In fact, sum takes a list and reports a single value. Given that the sum of a list of one value is exactly that value, in this case sum will report the only value in the list, but without square brackets.
When using sprout 1, you can make the new-born turtle assign itself to the patch: sprout 1 [set my-agent self]. This is possible because turtles can read and modify the variables of the patch they are on: in this case, the new turtle is able to operate on my-agent and, in particular, on my-agent of the patch it stands on.
I think that, between the three options above...
#2 is the least preferable: it never changes the fact that my-agent is an agentset (it only converts energy-of-my-agent from list to number at the end of the simulation), and I think this is not convenient in terms of memory and time because working with agentsets is a heavier process than working with agents.
#1 does not have this problem, because from the beginning it makes sure that my-agent is an agent and not an agentset (using one-of), so it is a better solution than number two. However, although it is perfectly fine, from a stylistic point of view using one-of <agentset> reads as if you're literally looking for a single random member of the agentset, instead of looking for the specific single member of the agentset.
#3 does not even have this latter problem: even from a syntactial point of view, this approach makes it very clear that each turtle, and only such turtle, is my-agent of the patch it sprouted from.
I'm trying to implement YOYO leader election algorithm in netlogo
first step in this algorithm is to orient links ( direct link )from the minimum to the maximumbut between neighbors only !
I tried the command
[`ask turtles with [ [ who ] of self < [who] of one-of link-neighbors ]
create-direct-to turtle [who] of one-of link-neighbors ]`
this creates direct link from min to max ( neighbors ) but also creates a direct link from max to min ( neighbors )
and I don't know what's wrong :(
here's a screenshot , if you notice theres' a direct link from 0 to 2 and also from 2 to 0 and my goal is to have only from 0 to 2
Your problem is that every time you do one-of, it randomly selects. So you test against a random link-neighbor in the first line, find it's true and then randomly select a link-neighbor to connect to.
[ ask turtles with [ [ who ] of self < [who] of one-of link-neighbors ]
create-direct-to turtle [who] of one-of link-neighbors
]
More generally, this seems an odd way to achieve your goal. To start with, link-neighbors are the turtles that the turtle is already linked to. link is the generic name for all link breeds (I think you have created a breed called direct-link).
I am not entirely clear what you mean by minimum and maximum since your code is just from smaller to larger who value, regardless of what other who values are available. If you want to create a link from every turtle to every turtle with a higher who value, here is some code:
ask turtles
[ let targets turtles with [who > [who] of myself]
create-links-to targets
]
In general, it is bad practice to use who in NetLogo code. who is a completely arbitrary identifier that simply tracks the order that turtles are created. If you have turtles that die, then your code may crash because it is referring to a turtle that no longer exists. Or perhaps at some point you will have two breeds of turtles - who doesn't care if your turtle is a person or a dog or a factory or...
This may be one of the very few exceptions, but you might want to think about what you are intending who to mean. For example, as this is a leadership model, perhaps you could have a variable called 'charisma' and all the links are from turtles with lower values of charisma to higher values of charisma.
Here is the code :
to new_neighbor
set my-neighbors (other patches) in-radius 2
end
to go
ask patches
[ set live-neighbors count my-neighbors with [living?] ]
;; Starting a new "ask patches" here ensures that all the patches
;; finish executing the first ask before any of them start executing
;; the second ask. This keeps all the patches in synch with each other,
;; so the births and deaths at each generation all happen in lockstep.
ask patches
[ ifelse live-neighbors = 3
[ cell-birth ]
[ if live-neighbors != 2
[ cell-death ] ] ]
tick
end
Here is the error:
COUNT expected input to be an agentset but got the number 0 instead.
Error while patch 30 -31 running COUNT
called by procedure GO
called by Button 'go-once'
I just want to extend my neighbors to 24 cell. Nothing else. I want program to check not first 8 cells ring but 24.
Thank you.
Look in the Models Library (File menu). In the Code Examples section, there is one called 'Moore & von Neumann Example'. That does exactly what you want.
For your error, there were no patches in my-neighbors. Your code doesn't include any section that actually sets the my-neighbors variable, so it's unclear why it was empty. That is, what bit of code actually calls the procedure new_neighbor?
I was finding my model was running very slow and I narrowed it down to an in-radius command that the turtles are running. The bottom line is that out of the two procedures below, test1 checks [var] of every patch but runs faster than test2 which should only check a small subset of 8 patches.
set patches-of-interest (patch-set patches with [var > 1])
to test1
ask min-one-of other patches-of-interest with-max [var][distance myself][set pcolor red]
end
to test2
ask min-one-of other patches-of-interest in-radius 1.5 with-max [var][distance myself][set pcolor yellow]
end
You can check their speeds using the Profiler extension and the following code:
profiler:start
repeat 100 [
ask one-of turtles [test1 test2]
]
profiler:stop
print profiler:report
profiler:reset
Firstly, why is test2 running slower? And secondly, is there an alternative to test2 which does approximately the same thing but more efficiently?
I found a couple discussions on the Netlogo list about this but they're a bit old so may be out of date:
https://github.com/NetLogo/NetLogo/issues/402
http://netlogo-users.18673.x6.nabble.com/Re-in-radius-efficiency-question-td5003840.html
EDIT: I left out that in my model I'm actually using a patch-set not the full "patches". I've updated the code example above, but Bryan already partially explained the reason for the slowdown in the comments. Bryan is right that if using all patches, test2 is much faster, but I haven't been able to subset the patches in advance or within the two tests without slowing down test2.
#bryan-head gave the reason for why the code is slow (in-radius checks on patch-sets cannot be optimized). I assume this is something internal to Netlogo's code.
However, I did finally find a work around that speeds things up and has the same effect so I thought I'd post it. First add the patch variable binaryvar then,
ask patches [ifelse var > 1 [ set binaryvar 1][set binaryvar 0]
to test3
ask min-one-of other patches-of-interest in-radius 1.5 with-max [var * binaryvar][distance myself][set pcolor yellow]
end
Of course this still fails if all the cells in-radius also have var = 0...
Hello i will try to be quick
I have a room with a fire that expands , and i have two exits , all i want to do is say to agents that if a door is blocked by fire then to go to the other one. i came up with something like this but not result.
to doorblock
show count neighbors with [pcolor = 77] ;; the patch color of the two doors
end
;;to go
ask smarts [ ;;smarts are the agents inside the room that need to get oout
if [ doorblock > 5 ]
[ set target one-of sexits]] ;;sexits is the other door
Anyone got a better idea? Thanks
OK, so if I understood correctly, you want your agents to take a look at the door that is their current target, check if that door has more than 5 fire agents around it, and choose another target door if that is the case.
If your fire agents are just red turtles (with no specific breed), you probably want something like this:
ask smarts [
if count ([ turtles-on neighbors ] of target) with [ color = red ] > 5 [
if-else ([ breed ] of target = sexits )
[ set target one-of nexits ]
[ set target one-of sexits ]
]
]
The key primitives here are:
neighbors, that will give you the patches around a turtle (the patches around target, in this case)
turtles-on, that will give you the turtles that are on members of a patch set (here, that will be the turtles that are on the patches that are the neighbors of target)
and finally, with allows you to get only the turtles from an agentset that satisfy some condition (here, we use it to get only the red turtles that represent the fires).
You should also try to understand the of primitive.
And I guessed you wanted to assign a new target that was of a different breed than the previous one (south if north, north if south) but that's up to you.