I have a simulation for a fire-evacuation, and the fire starts form different sources.
I want to simulate the exit with the least number of injuries, while having 3 exits it's 3 scénarios.
But my issue, is that the simulate each exit with different fire sources. How can I fix the same scenario for three simulations ?
Here is the code :
to run-all
clear-all
let temp (list ("left") ("right") ("top"))
foreach temp [
[a] ->
setup
set finished 1
if a = "left" [
while [finished = 1] [
go-to-left
]
]
if a = "right" [
while [finished = 1] [
go-to-right
]
]
if a = "top" [
while [finished = 1] [
go-to-top
]
]
]
end
I don't think that you need to change the code you posted here. The place to look is in your "setup" code, which you did not post.
Probably in your setup code you use "random" to create places for people to stand, so what you need is to have "random" generate the exact same locations for each of many different passes, so you can compare the different exits with the same starting conditions.
The way to do that is to set the "seed" that "random" will use ( secretly ) to exactly the same seed at the start of each pass you want to be identical.
Then if you want a new series of runs with different random locations, change the seed to a different number and use that at the start of each run
The command to do that is described in the User dictionary under "random-seed", where it also tells you See the Random Numbers section of the Programming Guide for more details.
Related
I am trying to update my model to NL 6 because the automatic update failed (mostly due to syntax for anonymous procedures). My model uses the rnd extension which now apparently comes bundled with NetLogo, but the example from the manual still mentions this:
extensions[rnd]
to go
let pairs [ [ "A" 0.2 ] [ "B" 0.8 ] ]
repeat 25 [
; report the first item of the pair selected using
; the second item (i.e., `last ?`) as the weight
type first rnd:weighted-one-of-list pairs [ last ? ]
]
end
This results in an error because "nothing named ? has been defined". I have been able to convert other things like foreach and n-values, but I am struggling with this example to the new notation required by NetLogo 6. Can someone help?
We missed a few cases when converting the rnd extension manual for bundling it with NetLogo. This will be fixed in NetLogo 6.0.1. In the meanwhile, you can refer to the most current version of the manual on GitHub:
https://github.com/NetLogo/Rnd-Extension/blob/hexy/README.md
In your specific case, the NetLogo 6 syntax would be:
rnd:weighted-one-of-list pairs [ [p] -> last p ]
In my study, I'm trying to build a simulation representing of a real work setting, with the aim of creating knowledge on how make people feel better at work.
In particular, I'm modelling a scenario where people work for more than one team (do you work on only one project at a time? Many don't...). To do this, I'm working with NetLogo.
I'm having a problem with an ASK to a specific agent of a custom link-turtle-set. The point is that sometimes it reports an error, saying that "ASK expected input to be an agent or agentset but got NOBODY instead", but it should not arrive to that "ASK" without the agent to exist! What am I doing wrong?
The function is the following:
to TeamRecruiting
;; I ask non-complete teams to...
ask teams with [ teamsize != (count membership-neighbors) ]
[
;; ... count how many individuals they have...
let actualteammembers count membership-neighbors
;; ... to save locally how many individuals they can share...
let teamoverlap overlap
;; ... their target size...
let neededsize teamsize
;; ... and their identity.
let teamwho who
;; then I ask those individuals that have not yet more things than they can handle...
ask individuals with [ indMTM != (count membership-neighbors) ]
[
;; ... to save locally who they are...
let indwho who
let createdalink 0
;; ... then if some conditions have been met ...
if(some conditions)
[
;; I create a link (of my specific type) with the team...
create-membership-with team teamwho
;; I do the following because more than one individual could join the team teamwho in the same run of the function
ask team teamwho [ set actualteammembers (actualteammembers + 1) ]
set createdalink 1
]
;; if the association occurred, ...
if(createdalink = 1)
[
;; we ask all other teams to evaluate if the new connection violates their maximum overlap constraint between the team I am considering from the beginning of the function, and all other teams, in other words...
ask teams with [ who != teamwho ]
[
let numpaths 0
let team2who who
;; I count how many individuals say that they are shared by the two teams
ask individuals
[
if((membership-neighbor? team teamwho) and (membership-neighbor? team team2who)) [ set numpaths (numpaths + 1) ]
]
;; ... and if the number of paths is more than the maximum allowed overlap...
if(numpaths > teamoverlap)
[
;; I take the connection away...
ask membership teamwho indwho [ die ]
;; and I reduce the actual number of team members
set actualteammembers (actualteammembers - 1)
]
]
]
]
]
end
Thank you for your precious help!
I think that the problem is likely to be in the way you refer to the link you are asking to die. membership is an undirected link and so which agent is end1 and which is end2 depends upon the order in which the agents were created. The one with the lower who number is end1 and the other is end2. So, if the team agent was created after the individual agent, that particular link would be membership indwho teamwho. In general, using who numbers at all is bad practice, but the same problem would arise if you used the team and individual agents themselves rather than their who numbers.
Someone with more experience in the use of undirected links than I might have better advice on how to easily refer to an undirected link when you don't know offhand which agent is the older, but something like
ifelse (indwho < teamwho) [
ask membership indwho teamwho [ die ]
]
[
ask membership teamwho indwho [ die ]
]
should work. Using directed links obviates this problem as the creator agent is always end1 and the target agent end2. So, if membership links always are created by the individual, you'll always know that the individual is at end1.
Hope this helps.
Charles
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.)
From each of the turtle's perspectives, I have to run a function for a turtle to decide which turtle it will assign as it's "buddy".
Right now I have the code below but it doesn't achieve the effect.
foreach sort other turtles [
ask ? [
if Smin < Sim myself ? and self != ? [
]
]
]
In C/Java it would've been simple, just a simple for loop and then that's it. Apparently I am having a hard time understanding NetLogo's foreach function and the integration of '?' in looping. How can I do this?
It's unclear from the code sample you posted what exactly you are trying to do.
Some things that may help:
Unless you want to address your turtles in a specific order, it's usually not necessary to use foreach. Just doing ask other turtles [ ... ] can replace the whole foreach sort other turtles [ ask ? [ ... ] ].
Given that you are inside an ask ? block, self != ? will always be false, and thus, so will the and clause of your if. The code inside your inner block is never reached.
myself refers the agent from an "outer" ask block (e.g., in ask x [ ask y [ ... ] ], self would be y and myself would be x). Neither myself nor self is affected by foreach, and ? is not affected by ask.
My guess is that maybe you just want:
ask other turtles [
if Smin < Sim myself self [
]
]
But I can't know for sure, especially since I have no idea what Smin and Sim are. If you post more detail, maybe we can help you further.
Finally: NetLogo code usually ends up being much simpler than the equivalent C/Java code, but you must learn to embrace the "NetLogo way". Thinking in Java/C and then trying to translate in NetLogo will usually lead one astray.
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.