Defining constants in NetLogo - netlogo

What are the available options (if any) for defining constants in NetLogo? I am looking at having the constants defined in the code, not in the interface. The value(s) are not intended to be received from the user as an input via the interface.
The goals are as follows:
Define the constant in one place in the code and use it wherever required. This would enable one to tweak the value in one place.
Prevent accidental modification of the constant value elsewhere in the code.
I am looking at creating something similar to the mathematical constants e or pi which are baked into NetLogo but at a single model level.
Is it possible to create such a constant?
Are there more than one ways to define such a constant? If yes, what are the available options and the associated pros and cons?

Two ways come to my mind:
(1) Use global variables that are specified upon setup
For example:
globals [
a-cool-number
a-number-that-I-don't-like
]
to setup
clear-all
set a-cool-number 7
set a-number-that-I-don't-like 44
create-turtles 1
end
to go
ask turtles [
show word "The best number is " a-cool-number
show word "The same is not true for " a-number-that-I-don't-like
]
end
Pros: It works.
Cons: The more global variables you declare, the less easy it becomes to approach your model by reading code (although using comments to single those variables out by saying that they are just constants would help). Also, in theory those variables could be accidentally modified by agents or by you (although I think this is a remote risk, if it is true that these variables are only specified upon setup and never again).
(2) Use reporter procedures
For example:
to setup
clear-all
create-turtles 1
end
to go
ask turtles [
show word "The best number is " a-cool-number
show word "The same is not true for " a-number-that-I-don't-like
]
end
to-report a-cool-number
report 7
end
to-report a-number-that-I-don't-like
report 44
end
Pros: It works. Also, there is no way the value of your constants could be inadvertently modified by agents and not even by you yourself (unless you directly go and change the code in the reporter procedure, of course).
Cons: None that I can think of now.
All in all, given the way you asked your question, I think that reporter procedures are the best option for you.

Matteo's answer is good, I'd use reporters, too. But I wanted to add one more method that's a little "sneaky". You can create widgets, inputs, sliders, or choosers, and then place a label widget with background transparency disabled over the top to "hide" them. Widgets are presented in the order they were added to the model, so the label widget gets drawn in last over the top of the other global variable widgets.
This lets you have a global variable that you can use in code that has no apparent backing widget. Any value you give it will be saved with the model and so will be "constant".
The only time I would use this technique would be if I really didn't want anyone looking at the model code to see where the constant value was coming from for some reason. I can't even think of too many uses for that, but hey, I just wanted to make the possibility known.
A big downside of this method is that you can change the value through the command center or other code and not notice it, as the value is hidden from sight.
Here is a picture that hopefully makes it clear. I've not completely hidden the input widgets and I've left text in the label just to make the picture not be a big blank area.

Related

How do I make a list of agent variables?

I'm trying to make my model compatible with an interface framework that can't handle the csvs I normally export to, and requires lists. What I need to do, specifically, is export a list of lists of variables associated with each of a certain breed of agent.
Ideally:
set master-list (foreach person set traits-list list (who) (color) (heading) (xcor) (ycor) (etc...))
But the primary issue I'm having is that after the first two variables set up in the set traits-list list (items) way, it starts throwing up errors on any subsequent variables. I can just lput each individual variable, but that seems like a really unnecessarily messy way to set it up. Am I missing something?
I've tried seeing if it's the individual variable that's the issue, but the error persists no matter what the third variable is.
If anyone wants to look at the complete code in question, I'm trying to make https://github.com/efyoungud/stationfire work with https://github.com/hlynka-a/SRTI.
JenB had the answer with needing the bracket.
Final, functional code:
ask people [ foreach [self] of people [
set traits-list (list (who) (color) (heading)(xcor)(ycor)(shape)(breed)(hidden?)(size) (alarmed?) (age)(visited?)(group-number) (group-type) (group-constant)(speed) (leadership-quality) (leader) (goal) (energy)(speed-limit)
)]] ; doesn't include next-desired-patch or path because that's calculated each step and doesn't need to be exported
set master-list [traits-list] of people
end ```

How to select output in Anylogic by agent parameter?

So, I'm pretty new with Anylogic, but have done a lot of tutorials and I have programming experience in Java. For my thesis I'm modelling a vehicle flow as a process. In the source block, I create custom agents (vehicles) with some parameters from the database. This works fine. Then I want to assign an electric parameter with randomTrue(0.5). For this, I call a setupTaxi-function, where electric ist set. The parameter for the randomTrue-function should be changeable, so I set it as an extra paramter anteilEtaxis (0.5).
After that, I want the vehicles to do different things depending on the value of electric using SelectOutput. I selected the Condition and test on agent.electric.
I basically did the exact same thing as described in the Anylogic help. And yet the framework always chooses the true Output port, no matter if the parameter ist set to true or false.
See the image for setup and parameters. I tested this via console (the first line is a println-call in source, the second a println-call in selectOutput.). Plus you can see that the parameter is set to different values, because the 3D visualisation model depends on it:
enter image description here
Also, I tried a few different combinations of setting the parameters, reading them etc... The only thing that will work is putting randomTrue(0.5) directly in the Condition box. This is not what I want though. So if you have an idea, what is wrong, please tell me.
This is a typical beginners problem.
I will assume you are calling the setupTaxi-function in your source in the "on exit" action... If you are doing that, then it's too late and the agent already made its decision on where it will go after the select output block.
You have to call your setupTaxi-function in 2 possible places:
1) In your source on the "on at exit" action
2) In your vehicle agent on the "on startup" action
Or even.. just make electric variable have a default value of randomTrue(main.anteilEtaxis)... that will also work.

Passing information between models in NetLogo LevelSpace

I am currently setting a multi-level model, and am hoping to use the NetLogo LevelSpace extension. I want the parent model to request the value of a global variable from a child model, but am having a little difficulty with the syntax. I can find examples of requests for information from agents e.g.
let turtle-id 0
(ls:report model-id [ [ color ] of turtle ? ] turtle-id)
but this doesn't seem to work for global variables e.g., I would like to do something like:
ls:report model-id [child-global-variable]
Is this possible, or am I completely missing the way that LevelSpace works?
ls:report model-id [child-global-variable]
will actually work just fine, though I slightly prefer using ls:of, just because it matches of:
[child-global-variable] ls:of model-id
That said, all the code that we're discussing right now requires the upcoming version of LevelSpace (which will run on the upcoming version of NetLogo, 6.0).
You can download the version that runs with NetLogo 5.3.1 here: https://github.com/NetLogo/LevelSpace/releases/tag/0.1
That version requires that code be passed between models in strings. So you have to do:
"child-global-variable" ls:of model-id
You can find the documentation for that version here: https://github.com/NetLogo/LevelSpace/blob/c3f78f45217e34cd31b18a246e4749e74209f29f/README.md
Sorry for the confusion!
I have found a solution: create a function in the child model that reports the variable:
to-report report-variable
report variable
end
Then, I can call this function from the parent-model:
show "report-variable" ls:of ls:models
Not sure if this is the most efficient way to do it, but it seems to work.

How to reset a NetLogo model with an extension?

I'm working on a NetLogo model that has a great deal of information stored in lookup tables and embedded in patches that affect agent behavior. As a result, I'm creating a model "reset" from an extension that clears the turtles, and resets the timer and ticks.
I would also like to have the extension reset specific globals that track model results, but not reset all of the globals that are constants (look up tables of precomputed information). I would also like to reset all the interface plots.
Any thoughts on how to go about this?
I apologize for no code to show, as is the case I can't show what is not working because I'm not even sure what to try!
NetLogo engine internals aren't really documented except in a general way at https://github.com/NetLogo/NetLogo/wiki/Engine-architecture, so if your extension wants to manipulate engine stuff directly, you'll usually have to consult the NetLogo source code to learn specifics of how it's done.
You want something like clear-globals, so check out https://github.com/NetLogo/NetLogo/blob/5.x/src/main/org/nlogo/prim/etc/_clearglobals.scala and https://github.com/NetLogo/NetLogo/blob/37cc1a0aa371c11e89f5b39b5143ed5d951e6081/src/main/org/nlogo/agent/World.java#L849-L866.
You want something like clear-all-plots, so check out https://github.com/NetLogo/NetLogo/blob/37cc1a0aa371c11e89f5b39b5143ed5d951e6081/src/main/org/nlogo/prim/plot/primitives.scala#L45-L50 and https://github.com/NetLogo/NetLogo/blob/37cc1a0aa371c11e89f5b39b5143ed5d951e6081/src/main/org/nlogo/plot/PlotManager.scala#L54-L57.
And so on.
EDIT:
For access to the PlotManager, note that plot/primitives.scala has:
workspace.plotManager.asInstanceOf[PlotManager]
in Java code on an extension, from the workspace plotManager() gets you the PlotManager, except the return type of that method is Object (yes, I know, it's grungy and horrible), so you need to insert a typecast to org.nlogo.plot.PlotManager and you're good to go. PlotManager has methods for getting to particular plots.

Loading Variable-Based Parameters in Behavior Search

I am using Behavior Search to calibrate my NetLogo model for 20 different hospital units. I am using global variables to set the min and max for several sliders in my model, but I think this is causing an error in Behavior Search when I attempt to load the parameter values from the model. However, I don't want to manually enter these parameter ranges manually each time I use Behavior Search.
Is there a way to get around this error? Is there a way to set the min and max for a specific slider to a constant, rather than using global variables?
Thanks for your help!
BehaviorSearch developer here -- if I'm understanding your question correctly, your NetLogo model has a slider which has a min/max constraint that is not set to a constant, but is instead set to a global variable (in the slider settings, accessed from the NetLogo interface).
When I choose such a model using the BehaviorSearch GUI, and then click the "Load parameter ranges from model interface" button, then I get the value of 0 for that constraint. (I don't see any error message -- just the value 0 (if you're getting an error message instead, then I may not be understanding your situation correctly, and perhaps you could post exactly what error message you're seeing?)
This will be true even if you are setting the slider min/max to a global value in the special STARTUP procedure (see: http://ccl.northwestern.edu/netlogo/docs/dict/startup.html), because STARTUP is only run when a model loads in the NetLogo GUI, and not when a model is loaded in headless NetLogo.
Thus, unfortunately, I think the answer to your question is: "no, there isn't a way to get BehaviorSearch to load the parameter ranges from global variables within the model".
Some possible work-arounds:
BehaviorSearch is open-source -- some changes could be made to it -- i.e., maybe adding in a call to "startup" whenever BehaviorSearch GUI loads the parameter ranges would be sufficient for you.
If you're only doing a few searches, I don't see why manually editing the parameter ranges would be particularly onerous. However, if you're generating a lot of different searches with this model, then I can see how it might be an issue. The .bsearch files are just XML text files, so you might consider generating them without the BehaviorSearch GUI, e.g. using a scripting language.