Agent garbage collection in NetLogo - netlogo

I'm using TSP to illustrate Genetic Algorithms in a class. The students are supposed to write the GA. There is a forever button that will run the GA continually. Whenever a new best path is found it is saved and displayed.
To show how this is supposed to work, I wrote a greedy-path procedure. Starting at a random node, it builds a path by taking the shortest link that attaches to an unused node.
Here is the (slightly simplified) forever button procedure that calls greedy-path.
to continual-greedy-path
let new-path greedy-path ;; Creates a new path agent
if [path-length] of new-path < [path-length] of best-path [
set-new-best-path new-path
display-best-path
]
end
Each call to greedy-path creates a new path agent to store the path. The problem is that I am running out of memory. With the continual-greedy-path button on, count paths keeps increasing and memory is chewed up rapidly, even though very few better paths are ever found. (There is only one greedy path from any starting point. So the maximum number of new paths is the number of nodes. The problem occurs even when there are only two nodes and no better paths are ever found!)
Are the unused path agents not garbage collected at the end of continual-greedy-path? Is there something else I'm missing?
The only new agents that are being generated are paths. There are no new nodes or edges.
Thanks.
Update: A bit of experimentation suggests that there is garbage collection. Perhaps it just can't keep up with the rate of new path generation. But why doesn't the system slow down rather than run out of memory?

It looks like the turtles created by continual-greedy-path are not removed, just the variable new-path. So, your paths are still present and their count increasing, as the new-turtles here:
globals [ max-x ]
to setup
ca
set max-x min-pxcor
reset-ticks
end
to new-max-x
let new-t new-turtle
if [xcor] of new-t > max-x [
set max-x [xcor] of new-t
]
end
to-report new-turtle
let x nobody
crt 1 [
set x self
set xcor random-pxcor
]
report x
end
I think the quick fix would be to manually remove those path agents that do not meet your criteria with something like:
globals [ max-x max-x-turt]
to setup
ca
set max-x min-pxcor
set max-x-turt nobody
reset-ticks
end
to new-max-x
let new-t new-turtle
ifelse [xcor] of new-t > max-x [
set max-x [xcor] of new-t
if max-x-turt != nobody [
ask max-x-turt [
die
]
]
set max-x-turt new-t
] [
ask new-t [
die
]
]
end
to-report new-turtle
let x nobody
crt 1 [
set x self
set xcor random-pxcor
]
report x
end

Related

How to choose the second highest value of a patch variable in NetLogo 6.2?

I'm having difficulty doing the following code: I have a piece of code that turtles inside an in-cone choose a patch that has resource > 30. When, the patch that turtle was the one that had the highest value a turtle did not move. So I put the line of code using the "other" command. However, what happens now is that if the patch the turtle is in has the highest resource value, it chooses another patch that has resource > 30. The problem is that there is, for example, a patch on the turtle's side that has resource value = 51 and another one that has a value of 31 and she chooses 31. What I would like to implement is: if the patch the turtle is in is the one with the highest resource value (and the turtle has already collected this resource) she would choose another neighbor patch that had the second highest resource value. I tried using max-one-of but got an error: "MAX-ONE-OF expected 2 inputs, an agentset and a number block.
Does anyone have any ideas, how can I solve this?
Thanks in advance
to go
ask turtles
[
let availablePatch patches in-cone 5 90 with [ resource-value > 30 ]
ask patch-here [ set availablePatch other availablePatch ] ;; remove the patch it is in, because if the patch it is in is the one with the highest value within your range of vision, the turtle does not move
; ask patch-here [ set availablePatch other max-one-of [ availablePatch ] ]
let neighAvailable count availablePatch
ifelse neighAvailable = 0
[
move-around
]
[
let target max-one-of availablePatch [ resource-value ]
face target move-to target
set step-count step-count + 1
]
]
end
to move-around
right random 360
let step-length 2
forward step-length
end
As is often the case with new programmers, you are too far caught up in a specific thought pattern. So you are making the problem really technical and the code bloated, when code should always reflect what you are trying to do. What you want is simple, so the code should be simple. try to zoom out and think of other options.
If I understand correctly, turtles should pick high-resource patches to exploit them/gather their recources. But they should not pick the same patch twice.
possible solutions that make sense:
-after a turtle has exploited a patch, resources should be below 30. that way it won't be a candidate. if it is not below 30, moving doesn't seem to make a lot of sense anyway.
-use a patches-own variable "exploited" that you set to "true" after the turtle has moved there, and to "false" after the turtle has left. Then you can use with [ resource-value > 30 & exploited = false ] instead of the current with check.

How to adjust a file (to remove []) to export result in NetLogo?

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.

NetLogo : getting turtles to direct-link if a condition is true

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.

Game of Life , NetLogo i Extend my neighbors to 24 cells using in-radius

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?

Communicating data between agents when they are in common scope in Netlogo

I am developing a model in Netlogo. I have many agents in my model. each agents must have a radio scope. Two agents can communicate with each other and transfer some critical data When they place in a common scope area.
Imagine that i have 100 agents with 5px scope and 200 agents with 3px scope. I have also 1 master agents that move around in the word. This master agent have a scope too(for example 7px) . Agents can communicate with each other when they place in common scope area. When they communicate they can transfer some of their data. At first just master agent have this critical data and just master agent can transfer this important data. But after he transfer its data to the other agents, those other agents that have this data can transfer this data too. The important condition is being in the common scope.
How can I do this?
Thank you
You just gave a very general statement of your problem. You will get better answers if you make the effort to actually start implementing something and ask about more specific difficulties that you are facing.
That being said, I made a small model that more or less fits with your description. Perhaps it could be useful for you as a starting point and you can ask separate (more precise) follow up questions if you have some.
turtles-own [ scope data ]
to setup
clear-all
; make a big world so agents don't
; bump into one another right away:
resize-world -100 100 -100 100
set-patch-size 3
; create turtles and distribute them around:
crt 100 [ set scope 5 set data "" ]
crt 200 [ set scope 3 set data "" ]
crt 1 [ set scope 7 set data "important data" ]
ask turtles [
set size 3
setxy random-xcor random-ycor
recolor
]
end
to go
ask turtles [ travel ]
ask turtles with [ not empty? data ] [ share-info ]
ask turtles [ recolor ]
end
to travel
; you haven't specified how turtles should move
; so here's a classic "wiggle":
rt random 30
lt random 30
fd 1
end
to share-info
ask other turtles in-radius scope with [ empty? data and distance myself < scope ] [
set data [ data ] of myself
]
end
to recolor
set color ifelse-value empty? data [ grey ] [ red ]
end
Edit:
Following Seth's comment that my first version probably didn't capture the idea of a common scope, I've added and distance myself < scope. This way, only turtles that can see each other can share information.
I've also added a with [ not empty? data ] clause when asking turtles to share info, because there is no use in having turtles with empty data share it.