How can I use breeds-own or turtles-own variables in BehaviorSpace. When I tried it I got an error that "Global variable does not exist".
I cannot use these variables as global variables as each breed/turtle needs to have its own unique value of the variable during each run.
You cannot use breeds-own or turtles-own variables in BehaviorSpace.
You normally use breeds-own or turtles-own variable when you want a potentially unique value for each single individual. If that is what you want, trying to set that through BehaviorSpace is not going to work. (Though we may be able to suggest a workaround if you explain what you need in more detail.)
If you just want a unique value for the whole breed, then it's easy. You can create a different global variable (normally with a slider widget or numeric input box) for each breed. Let's say you have the following breeds:
breed [ frogs frog ]
breed [ mice mouse ]
Then you can have a slider named mice-var and another named frogs-var, and refer to those whenever you need to access that value in your code. For example:
to setup
clear-all
create-frogs 10 [
set label frogs-var
]
create-mice 10 [
set label mice-var
]
end
In BehaviorSpace, you can then vary both of your global variables:
["frogs-var" 1 2 3]
["mice-var" "A" "B" "C"]
and then you'll have a run where all the frogs are labeled 1 and mice are labeled A, another run where it's 1 and B, then 1 and C, 2 and A and so on...
Related
With the use of the myself primitive, I want a patch with a certain land use to make buildings of that type in a specific radius, but it's not working. Here is the code:
patches-own [land-use] ;land-use can take many types: "residential", "industrial", "commercial"
...
to grow
ask patches with [land-use = "residential"]
[ask other patches in-radius 10 [
if [land-use = "residential"] of myself [build-house]]]
end
How can this be fixed?
The problem there is not myself but the use of of. Two things to fix:
of requires the reporter to be in square brackets. Only the reporter that of refers to, not the whole condition being tested (as in your case where you are testing a condition).
You should not specify the value of the variable but just its name. Just as in normal language: you wouldn't say "If your hair colour equals my blonde", but you would say "If your hair colour equals my hair colour".
The resulting syntax is:
if (land-use = [land-use] of myself) [
build-house
]
Parentheses surrounding the condition are optional, I use them as a stylistic choice.
PS Regarding point 2 above... of course you could keep the value of the variable (i.e. "residential") instead of the name of the variable (i.e. land-use), and in that case drop of myself.
You would have:
if (land-use = "residential") [
build-house
]
And as of now it would work because the patches starting this process are just those with land-use = "residential"... but this doesn't look like great code, as it is not extendable to other variable's values and it contains more hard-coding than necessary.
I was trying to personB's own variable to update in personA's own list type variable. when I tried to run this code i recived an error message "PERSONB breed does not own variable LEDGER
error while personbs 1 running LEDGER, called by procedure UPDATE-LEDGER...."
I cant change the ownership(If I make it global others can alter). how can I solve this?
My code is:
breed [personAs personA]
breed [personBs personB]
personAs-own [
wallet
ledger
]
personBs-own [
packid
batch-num
]
to start
ca
create-personAs 1 [
setxy random-xcor random-ycor
set shape "person"
set ledger []
]
create-personBs 1 [
setxy random-xcor random-ycor
set shape "person"
set packid 10
set batch-num who
]
update-ledger
end
to update-ledger
ask personBs [
set ledger fput (list packid batch-num) ledger
]
end
[Before starting: please note that in NetLogo breeds are defined first in their collective form and later in their individual form, e.g. breed [cats cat] instead of breed [cat cats], so you should change your breeds declarations accordingly. I'll give my answer as if you used the correct declaration, e.g. breed [personAs personA]. Also, note that breeds in NetLogo are not sensible to lower/upper case, so in general you might also want to give more meaningful names to make it easier to read]
--
It is possible to change turtles' breed by just asking them to
set breed newbreed
This will change their breed and, accordingly, all their breed-own variables (i.e. the turtle will lose its previous breed's variables and will gain its new breed's variables).
However your problem seems to be more fundamental: why did you make ledger a personAs-own variable if you want personBs to use set ledger? This is the crucial point.
There are two possibilities here:
You want each turtle to have a ledger to operate on. In that case, ledger must not be a personAs-own variable; it has to be a turtles-own variable (or, if in your full model you have other breeds who do not need ledger, then make it both a personAs-own and personBs-own variable). In any case, no global variables involved (a global variable only has one value for everyone, so that's not what you need).
You want personBs to be able to operate on the ledger of personAs. In that case, personBs will have to ask personAs to modify their ledger; or, alternatively, some personBs can operate on the ledger of some personAs by indeed using the of reporter (see here); for example:
; Solution with 'ask':
ask one-of personBs [
ask one-of personAs [
set ledger 10000
]
]
; Solution with 'of':
ask one-of personBs [
set [ledger] of one-of personAs 10000
]
Important update
Your expression "If I make it global others can alter" suggests me that you're thinking in terms of other programming languages, where you classify variables based on the level of access to that variable that other parts of the programme have.
Note that this is not the case in NetLogo: all parts of the programme (in this case: all agents) have access (even if indirect) to every variable through ask and/or of. No matter whether a variable is turtles-own, links-own, breed-own or patches-own. Every agent can read any other agent's variables. But also: every agent can modify any other agent's variables (see the code examples that I made regarding point 2 above). Therefore, making a variable something-own simply means that those are the agents carrying that variable.
How is it possible to change specific variable of an agent by passing variable name to a function?
for example I have turtles with variable MONEY and the following function:
to setVariable [varname varvalue]
[
ask one-of turtles [ set varname varvalue ]
]
end
Now I want to run:
observer> ask one-of turtles [setVariable MONEY 100] ;; I need to ask via another turtle since I cannot use MONEY directly in observer context
And it does not set my variable without giving any errors.
Interestingly, you can read a variable in similar manner:
to showVariable [varname ]
[
ask one-of turtles [ show varname ]
]
end
So the question here is how to "convert" my function input into turtle's variable name it would recognise well for SET purposes.
PS: I don't want to use run function as it would slow down the model.
In a similar situation where there are a number of possible options, I create a task for each and put them in a lookup table (using the table extension) with a string key for each. Then I can lookup the appropriate task for any key. It saves having the nested if/else structures, but I haven't investigated the efficiency of the table lookup.
You're correct that run with strings would slow down your model, but if you use run with tasks, it won't.
Here's your setVariable procedure rewritten to use tasks:
to setVariable [setter value]
ask one-of turtles [ (run setter value) ]
end
When you call it, the call will look like:
setVariable task [ set money ? ] 100
But this won't help you if at the call site, there's no way to avoid using strings.
If you must use strings, and it must be fast, then you have no choice but to write out a big ifelse chain that lists all of the variables that you need to support:
to setVariable [varname varvalue]
ask one-of turtles [
ifelse varname = "money"
[ set money varvalue ]
[ ifelse varname = "food"
[ set food varvalue ]
...
]
end
For reading variables, instead of setting, you can safely use runresult with a string containing the variable name without needing to be concerned about performance, since runresult caches the compiled strings, so it will be fast since you'll be passing the same strings over and over. (The setting case is different because the strings you'd be passing to run would be different all the time.)
I am implementing an evacuation simulation of a lecture hall.And i have two types of students those who sit on tables and extra students who allocated randomly inside the class.So i created two sliders in order to allocate the students at the desired numbers.The sliders are named extrastudents and standarstudents. When the simulation starts i want all the students (both in tables and extras students) to go to the nearest exit ( i have two exits ) .So i implemented that for only the students that are seating down :
ask standarstudents [
ifelse pycor > 0
[ set target one-of nexits]
[ set target one-of sexits]
face target
]
Nexits is the north exit.
Sexits is the south exit.
The problem is that i get this error and i can move on :
ASK expected input to be an agent or agentset but got the number 3 instead.
error while observer running ASK.(The number 3 derives from the slider that user is pick)
called by procedure SETUP
called by Button 'setup'
org.nlogo.nvm.ArgumentTypeException: ASK expected input to be an agent or agentset but got the number 3 instead.
any ideas?
Well, if you have sliders named extrastudents and standarstudents, those two variables are numeric values representing how many students of each kind you want, not the students themselves. Like the error message says, the ask primitive works with agentsets that represent "who you are asking".
Have you actually created your students? Putting sliders on the interface won't do anything by itself. I would suggest renaming your sliders to something like num-extrastudents and num-standarstudents and then using code like this to initialize your population:
breed [ extrastudents extrastudent ]
breed [ standarstudents standarstudent ]
to setup
create-standarstudents num-standarstudents
create-extrastudents num-extrastudents
end
Then, the code you have posted would work because extrastudents and standarstudents would be breeds of turtles, and thus, agentsets.
In netlogo I have a procedure that calls another procedure. How can I go about getting the value
for example, I have two breeds of agents, a hub and a link. A hub has a local variable called 'budget' and I'm trying to modify its value.
hubs-own [
budget
]
to go
ask hub 0 [
do-ivalue
]
end
to do-ivalue
ask links [
;; I'm trying to set the local variable budget of the hub that's calling this link
set self.budget newvalue ;; this is obviously wrong, how can I fix this?
]
end
what you want to do is use is 'myself', it refers to the caller (asker): the one who asked to run the code where the 'myself' is located.
to do-ivalue
ask links [
ask myself [set budget 10] ]
end
The 'self' refers to the agent running the code. It is similar to 'this' in Java.
hmm.
not sure why u want to do it this way..
what u can do for now is
ask links[
let new_value new_value_from_link
ask hubs[
set budget new_value
]
]