How to generate turtles at random time intervals and at random points in NetLogo - netlogo

I am quite new to NetLogo, so I need some help figuring out a few things.
I have a requirement to generate turtles at random points and intervals when the go button is clicked. I have written the code mentioned below, but it generates turtles only when I click on the go button, and they are not moving properly. The go button I am using is a forever one, not the single-step button. Kindly help me where I am doing wrong.
to go
repeat num-students[
every t [
set t random 60
create-students 1 [
set xcor random -32 - 32
set ycor random -13 - -15]
ask students [
set size 2
set color blue
set heading ( 90)
forward random 10
]]]
end

I strongly recommend not using "every" -- it executes something every specified number of seconds in real time, which is very different from at random simulated times. You need code that decides at which ticks turtles are created. (I did not even know "every" existed until seeing this and have never seen it used.)

My first suggestion would be to indent your code, that makes it much easier to see which command fits into which block. You can do this by simply highlighting all of your code and clicking tab.
I am not very familiar with the every primitive but the following code works as intended and I can't seem to reproduce your problem of no extra turtles being made. Maybe it is just that your time interval is too big?
to setup
ca
set num-students 5
set t random 5
end
to go
every t [
set t random 5
create-students 1 [
set xcor random -32 - 32
set ycor random -13 - -15
]
ask students [
set size 2
set color blue
set heading ( 90)
forward random 10
]
if count students >= num-students [stop]
]
end
I removed the repeat num-students[] part since it didn't add anything to the code. It just makes you repeat the every command a few times inside each tick. Instead, I used if count students >= num-students [stop] in order to stop when the desired amount of students is reached.

Related

NetLogo input slider problem, slider disappearing after reset

I want the max value of my input slider to be equal to the number of turtles in my environment. I've done this by inserting "count turtles" in the maximum input box in the slider settings. However, the problem I am facing is that when I (significantly) decrease the number of turtles and setup/reset the slider sort of glitches, stays on the old value (which is larger than the new max value which causes the red knob to disappear) and cannot be changed anymore. A workaround could be to drag the slider completely to the left before resetting the model but this does seem somewhat silly imo. Does anyone know how to fix this? Thanks in advance.
In my minimal working example, I could reset the slider value to turtle count, e.g. during setup. I think you could use if slider_value > count turtles [set slider_value count turtles] also in the end of the go procedure, in case the number of turtles decreases in your model and you want to keep the slider value updated.
globals [
; n_turtles - given by slider
; slider_value - given by slider
]
to setup
clear-all
crt n_turtles
if slider_value > count turtles
[
set slider_value count turtles
]
end

How to kill and regenerate turtles every set number of ticks

The model I am working on simulates a group of workers working on a team project. I am trying to add a on/off switch titled "replacement." The intended outcomes are:
When it is on:
30% of existing turtles of breed employees die, and equal number of new turtles are introduced.
When it is off:
No turtles die, and all turtles generated at setup will work on the project from start to finish.
The purpose of killing off the turtles is the turtle-own variable "skills." I am trying to simulate a scenario where people resign from a company and new people are hired, which will result in a change of skill level.
If it is easier to change the skill level of 30% of turtles every 20 ticks instead of killing/regenerating, that would be perfect, but I was unable to figure it out.
My attempt at this problem is shown below. It runs without any errors, but I confirmed that it's not killing/respawning 30% of turtles every set number of ticks. Any helpful guidance will be much appreciated.
to go
if all? patches [ workload = 0 ] [ stop ]
ifelse replacement [hire] [continue]
recolor
tick
end
to hire
if ticks > 0 and ticks mod 20 = 0 [
ask n-of (count employees * 0.30) employees [die]
create-turtles number_of_workers * 0.30 [
set breed employees
setxy random-xcor random-ycor
set shape "person"
set color black
set size 1
set skills random-float 1]
]
ask employees [move]
ask leaders [move]
end
to continue
ask employees [move]
ask leaders [move]
end
I ended up finding the answer on my own. Removing "ticks > 0 and" from the hire function solved it :)
From your description of the problem, I am not sure why removing the if ticks > 0 and solved it. I am wondering if you perhaps had the "replacement" variable set to false, and the hire procedure would not have been called.
Regardless, you also asked about just changing the skill set every 20 ticks. You could do this:
to go
if all? patches [ workload = 0 ] [ stop ]
if replacement? and ticks mod 20 = 0 [hire]
move-people
recolor
tick
end
to hire
ask n-of (count employees * 0.30) employees
[ set breed employees
set skills random-float 1
]
end
to move-people
ask employees [move]
ask leaders [move]
end
I also reorganised slightly in a way that is intended to make it easier to debug. You had the moving in both the "hire" and "continue" procedures. Clearly you want that to always happen, so that is now explicit in the "go" procedure (and I changed the name to be more descriptive).
Now the "hire" procedure simply changes the skills of existing employees. Note, however, that any other variables (such as leader, size, colour and position) are not affected. If you go this approach, you may want to indicate in some way that they are new hires.
The "hire" procedure is now clearly called when the "replacement?" switch is on and also a multiple of 20 ticks. If you have part of the condition in the calling procedure ("go") and part in the procedure itself ("hire") then it's easy to forget the existence of whichever half you are not looking at.

Please Assist with Netlogo Model

Please let me preface this with I am not a programmer by trade. I am a social scientist using M&S for some research. That being said, my goal is to use ABM (Netlogo) to create a model of state antifragility. That is a model of states that get better under stress rather than deteriorate or are resilient (return to their pre-stress levels).
The idea for this model is simple. Create agents (states) that have three properties-loops, capacity and performance. The Capacity of a state is defined as it's Agility + it's Learning + it's Power Conversion. ( I've done some regression analysis to see what the relationship between each of these variables and stress is and they are listed below. ) The state also has two loops-fragile and antifragile that are always running, but depending on the performance value and the stress value only one of those loops will activate to update the capacity/performance values to deal with the next stress. Finally, a state's performance ties all those together. That is, it is a function of capacity and stress.
States randomly roam about the world full of shocks (red patches with an intensity value). When the state comes across the patch, it interacts with that patch. To interact, it activates a loop and then performs and update of its capacity and it's performance for the next stress. This happens until a state dies (it's too fragile and fails) or it becomes the maxium value of antifragile.
UPDATED CODE BELOW ( 22 July) JenB, I took your advice and stripped it down to it's basic parts by removing the looping functions. Eventually, I'd like to get there in a future iteration, but for now I removed it. The code below is my stripped down, updated version. Where I am stuck is the stop movement function.
Starting with the latter, I am still unsure how to set something true or false. I kept getting an error about a string not a value for that command. (Again, I am really, really a beginner at this and even reading the Netlogo Dictionary isn't that easy for me.)
Now that I think about it there is a third thing. I'd also like to randomize the value of the red patches ("shocks"). I believe the way I have it set up right now is that they all have the same value, but I'd like some to be bigger or smaller.
Thank all of you for all your help in this journey!
Please see the code below:
breed [states state]
states-own [learning powerconversion agility performance category]
patches-own [intensity]
;; TO SET UP ;;
to setup
clear-all
grow-shocks
set-default-shape states "dot"
create-states 10 [
setxy random-xcor random-ycor
set color blue
set size 2.5
set performance random 100
set learning random 10
set powerconversion random 10
set agility random 10
]
reset-ticks
end
;; TO GROWN SHOCKS ;;
to grow-shocks ;; to grow shocks in the international environment do the following:
ask n-of number-shocks patches [
set pcolor red ;; make them red
set intensity random 10 ;; set their intensity to a random number between 0-10
]
end
;; TO GO ;;
to go
ask states [ ;; ask states to do the following : move, interact, update-category (AF, R, F)
move
interact
update-category
]
tick
end
;; TO MOVE ;;
to move ;; to move do the following:
right random 15
left random 15
forward 1
if abs pxcor = max-pxcor
[ set heading (- heading) ]
if abs pycor = max-pxcor
[ set heading (180 - heading) ]
end
;; TO INTERACT ;;
to interact ;; to interact with shocks do the following:
if pcolor = red [
set pcolor black set intensity 0 ;; if the patch is red, turn the patch black and set intensity to 0
update-performance ;; update-performance
update-category
]
end
;; TO UPDATE PERFORMANCE ;;
to update-performance ;; to update a state's performance do the following:
set performance (((-0.13 * learning ^ 3) + (1.89 * learning ^ 2) + (-5.72 * learning) + 8.13 ) +( 0.09 * agility ^ 3) + (1.29 * agility ^ 2) + (-3.45 * agility) + 5.57 +( 0.02 * powerconversion ^ 3) + (-0.89 * powerconversion ^ 2) + (9.93 * powerconversion) + -17.51 )
end
;; TO UPDATE STATE TYPE;;
to update-category ;; to update the state's type do the following:
if performance > 75 [ ;; if the state has a performance value of over 75, turn it green indicating an antifragile state
set color green
]
if performance < 74 and performance > 35 [ ;; if the state has a performance value between 35 and 74, turn it yellow indicating a robust state
set color yellow
]
if performance < 34 and performance > 5 [ ;; if the state has a performance value between 1 and 34, turn it red indicating a failed state
set color red
]
So I am guessing the line throwing the too large error is this one:
to activate-antifragileloop
set performance e ^ performance
end
This seems like a logic error to me. From the rest of your code, I am guessing performance numbers are generally in the range 0 to 100. Do you realise that e^100 = 2.6881171 x 10^43? It seems unlikely that you want performance to switch between numbers like 100 and numbers with 43 digits. I can't imagine a real world situation that you could be trying to represent where a key characteristic of the entities in the system has such a wildly varying value.
On the question of stopping, I would have another variable named something like done? that starts as false then you set it to true when you want it to stop. Then you can simply have ask states with [not done?] instead of ask states for any code that moves them around etc.
You said you are not a programmer. One of the best things a beginner can do is to make only minimal changes at a time. You have several problems with your code - this should almost never happen. Your life will be much easier if you only make one change at a time and get it working correctly before moving on. This is particularly important with NetLogo where it can be very difficult to work out whether something is working correctly because you are modelling systems that interact - how do you know whether the interaction is producing the results or a bug is producing the results?

Set value of speed slider programmatically

In setup, I draw a bunch of turtles--as small circles--to display two curves defined by functions. A very simple way to do this is
ask patches with [pycor = (myfunction pxcor)] [sprout 1 [...]]
and that's what my code does at present. It's kind of wasteful, since every patch has to be consulted--in random order--for each curve, but it's simple and easy to read, and it only happens during setup.
However, there's a little bit of a pause as the curves are constructed. If I move the speed slider all the way to the right, the pause is not noticeable. If I wrap the curve display routines in no-display and display, the user doesn't see the curves being constructed, but the speed is unchanged, AFAICS. If I move the slider to the left, it takes a long time to construct the curves even with no-display; the user doesn't see the points being placed one by one, but nevertheless has to wait while twiddling her/his thumbs.
Is there a way to set the model speed programmatically (for normal, "headfull" use)? I don't want to tell users "Move the speed slider to the right, then press setup, then move it back to the center before pressing go.
If not, maybe I'll code the curves properly using loops, but I thought I'd ask. Seems like there would be a way to do this, but I haven't found anything in the dictionary or programming docs so far.
(edit: no-display, if it did help, isn't available in NetLogo Web, which I am targetting along with regular NetLogo.)
I don't believe there is. However, you are asking all patches, when you could simply ask the pxcor values. This should speed it up a lot - square root of the number of iterations if a square world. Something like:
to testme
clear-all
let counter min-pxcor
while [counter <= max-pxcor]
[ let fn-out (function counter)
if fn-out >= min-pycor and fn-out <= max-pycor
[ ask patch counter fn-out [ set pcolor red]
]
set counter counter + 1
]
end
to-report function [#invalue]
report #invalue ^ 2
end

Is there an else command in netlogo?

I am trying to create a program in netlogo where there are blocks that come down the screen and when their y-coordinate reaches a certain value they reverse their direction and move in the opposite way.
So far I was able to make them move in one direction and then switch directions when they reach the critical y-coordinate value, but once they take one step in the reverse direction it glitches and they get stuck moving one step forward and one step backward.
I wanted to know if there was an else command in netlogo so I could specify that if the while command wasn't fulfilled it could reverse its direction and move without glitching.
Here is my code.
to maze
while [abs pycor < 16 ] [fd 1 wait .1]
bk 1 wait .1
end
There is no separate else keyword in NetLogo, but the ifelse command allows you to specify two blocks: one that is executed if the condition is true, and another (the "else" block) that is executed if the condition is false.
It seems, however, like you should rethink your general approach to the problem. Turtles in NetLogo always face in a particular direction, and you could take advantage of that: instead of having them "back up", you could have them turn around.
Also, it's generally ill-advised to try to do things in a while loop. If you want your turtles to repeat a behavior, a "forever button" is usually the way to go.
In the following example, you should call the go procedure from a forever button:
to setup
clear-all
ask patches with [ pycor = max-pycor - 1 ] [
sprout 1 [
set heading 180 ; head down
]
]
reset-ticks
end
to go
ask turtles [
if abs pycor = max-pycor [
rt 180 ; turn around!
]
fd 1
]
tick
end
This probably doesn't achieve exactly what you wanted, but there is a good chance that you can modify it to fit your needs.
Also note that this will work better using tick-based updates.