I am currently making a simulation (for homework) using genetic algorithms. What I want to do is compare the fitness of agents on a specific patch and the one with the lowest fitness will die.
I have scoured the net and found this code: if any? breed1-here with [fitness > fitness-of myself] [die]]
But this doesn't seem to work and now I'm completely out of ideas.
let goner min-one-of breed1-here [fitness]
if is-turtle? goner [ ask goner [ die ] ]`
the is-turtle? check is necessary because the patch might be empty.
Yes, that code is from an old version of the NetLogo language. That line of code should be re-written as:
if any? breed1-here with [fitness > [fitness] of myself] [die]]
Of course, that code will kill all turtles in a patch except for the one(s) with maximum fitness, which is not exactly what you want.
Related
I have a model that tracks energy levels in sheep, which I have defined as a breed. I have set up a monitor to calculate the mean energy level for the sheep, but need to consider what happens if there are no sheep at some point. I have tried numerous variations, the simplest of which is:
ifelse (any? sheep) ["NA"] [mean [energy] of sheep]
Unfortunately, I keep getting the error
Expected reporter.
I can work around this by creating a new global variable and reporter in the code, but this seems to be a bit of a waste. Am I doing something wrong or are there limitations on what kind of calculations can be done in a monitor on the Interface? If so, where are these limitations summarized?
Answer in three steps:
Difference between ifelse and ifelse-value
You are getting a syntax error there because a monitor expects a reporter, but ifelse is made to handle commands. The reporter version of ifelse is ifelse-value. If you just change ifelse to ifelse-value in your example, you see that you don't get any syntax error anymore. However, you will also see that if you do so and start your model with sheep having their energy, the monitor will show NA - see next point.
Correct use of any?
This happens because you are using any? the other way around. As you can see, any? reports true if the agentset is not empty. This means that the following reporter:
ifelse-value (any? sheep) ["NA"] [mean [energy] of sheep]
will report "NA" when there are sheep in the model, because that is the first reporter block.
Switch to:
ifelse-value (any? sheep) [mean [energy] of sheep] ["NA"]
and you have what you want. Just as in English: "If there are any sheep, do the calculation, else, this does not apply".
In any case, this does the job but it is superflous - see next point.
What monitors can do
Monitors are able to handle some of their reporters' runtime errors. You can simply put mean [energy] of sheep in your monitor and it will automatically show N/A when there are no sheep, without the need for you to handle the case.
I'm writing a program that is testing the ability of turtles to navigate in an environment. This line of code has two checks. I want it to kill off the oldest turtle that has made the least amount of progress. It does what it is supposed to, but the program slows down dramatically, creating little hiccups every time it makes this check. I was wondering if someone knew a better way to go about this or make this line more efficient. Thanks!
ask one-of turtles with [XCOR = min [XCOR] of turtles with [age = max [age] of turtles]] [
die]
First of all, there are primitives that are specifically finding the turtles with maximum or minimum values of some variable using min-one-of or with-min. So your code would look something like this I think:
ask min-one-of (turtles with-max [age]) [xcor] [...]
I suspect that would solve your efficiency problem, since it may well be because of implicit brackets not being where you think they are so it's trying to loop everything a couple of times. But a much cleaner to read version that would solve the efficiency problem is to specifically limit the position loop to those who are oldest and then choose the lowest position from that set.
let old-turtles turtles with-max [age]
ask min-one-of old-turtles [xcor] [...]
I have a list of parcel agents. but I will kill the parcels periodically. However, the list is still recording someting like this: [nobody nobody nobody nobody nobody nobody nobody nobody], and overtime the running of the model is getting slower and eventually pop up message "your model is too large to run with available memory"
In this case, are the dead agents (i.e. nobody) still treated as an agents that consumes much of the memory? what if it is a pure list of numbers or strings? would it cause the same OOM issue? how big the list can be in Netlogo and any uppper limit?
From, the NetLogo dictionary for die: If you have a list of agents and the agent dies, then the agent is removed from any agentset and:
The agent will disappear from any agentsets it was in, reducing the size of those agentsets by one.
Any variable that was storing the agent will now instead have nobody in it
The dead agents are not consuming resources, but the list is (as you have found by printing out the list). You can see this with the following model:
globals [mylist myagentset]
to setup
clear-all
create-turtles 1
set mylist sort-on [who] turtles
set myagentset turtles
reset-ticks
end
to go
create-turtles 1
[ set myagentset (turtle-set myagentset self)
]
set mylist lput one-of turtles mylist
ask one-of turtles [die]
type "turtles: " print count turtles
type "list: " print length mylist
type "agentset: " print count myagentset
tick
end
If you want the dead turtle to be removed from the list, you need to explicitly do so with remove-item. The same is true of lists of numbers, strings etc.
Alternatively, if the list doesn't need to be maintained over ticks, but can be reconstructed (eg if it is a sorted list of the turtles agentset), you could create it each tick and that list would only contain turtles that are alive.
How equivalent are the following two lines of code?
ask agentset [if (attr > 0) [dosomething]]
ask agentset with [attr > 0] [dosomething]
Are there any expected (and explainable) differences
in speed or the use of memory?
In particular, does the use of with in the second
case lead to the creation of a temporary agentset,
or does the ask ... with combination ensure
lazy evaluation?
Just to expand on what Nicolas said:
ask-with is intentionally not lazy. Consider code where the agents are modifying the attribute of other agents that determines whether or not they should be asked, so to speak:
to go
ask patches with [ pcolor = red ] [
ask neighbors4 [ set pcolor red ]
]
tick
end
Because with creates a temporary agentset, which agents are asked is not changed mid-ask. This causes the red region to grow evenly as go is called repeatedly:
Now, consider it with if instead.
to go
ask patches [
if pcolor = red [
ask neighbors4 [ set color red ]
]
]
tick
end
Because patches that have not been asked yet might have have their color changed to red, the red region grows unevenly:
Thus, ask-with actually has different behavior then ask-if, and so cannot be optimized to it. That said, as Nicolas mentioned, some similar optimizations are done.
(Disclaimer: my familiarity with the compiler is very superficial, so I might be missing something.)
A (possibly outdated) list of the optimizations performed by the NetLogo compiler is available here:
https://github.com/NetLogo/NetLogo/wiki/Compiler-architecture#optimizer
The actual code for those (in NetLogo 6.0) is here:
https://github.com/NetLogo/NetLogo/blob/bd3da2bf5495674ce5690cbb2992de4036c9db03/netlogo-core/src/main/compile/middle/optimize/package.scala
As far as I can tell, there is no optimization for ask ... with. It means that ask ... with does create an intermediate agentset and, as such, probably requires more memory and time than ask ... [ if ... ].
Which one you should use probably depends on where you stand on the efficiency/readability trade-off. (I personally find ask ... with more readable.)
Would it be a good idea to optimize ask ... with? In my opinion, absolutely. That being said, there might have been a technical reason not to do it at the time the compiler was written. I just don't know about it.
There is, indeed, a very good reason why ask ... with is not optimized. And there are behavioral differences between the two versions; it's not just a matter of readability vs. efficiency. See Bryan's answer.
I built a model that each turtle has their own strategy, and they will earn money according to their strategy.
Therefore, Turtles will own money, and strategy.
I want to rank top10 turtles who has the most money, and want to see which strategy that they have.
Is there any way that I can show it?
You can use max-n-of to get the top 10 agents and ask them about their strategy.
Something like
ask max-n-of 10 turtles [money] [show strategy]
To sort the result use sort-on:
foreach sort-on [(- money)] max-n-of 10 turtles [money]
[ ask ? [ show strategy ] ]