My Netlogo code is running fast in the first hundreds of ticks and then the speed decreases progressively after that (each new tick takes more and more time to proceed).
I have narrowed down the problem to this line of code:
ask turtles [
(foreach vectorX indexes
[
set minilist ?1
set minilist map customProcedure minilist <-- this line
set vectorX replace-item ?2 vectorX minilist
])
]
If this line is commented, the speed does not decrease. It is basically applying a custom procedure to each element of "minilist", and this custom procedure is just a succession of "ifelse" conditions.
An interesting phenomenon is that if I pause my simulation (I click on "Go") and restart it from the same place (I click on "Go" again), I get the original fast speed back. It is as if this line of code consumes a lot of memory but this memory would be reset when I stop the simulation.
Do you know what could be causing this problem?
Related
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.
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
i want to count the turtles which cross the line - i tried with "turtle on patch" but if the turtle stop it counts twice. If the turtle moves more then 1 patch it counts nothing...
any ideas? Thanks Peter
Line
From the picture you added it looks like you are running a single-lane traffic model with a very narrow "finish line" that turtles can cross entirely in one tick.
To catch crossings:
One thing you could do is make a thicker "line" on the far side of the finish line. Maybe make it 5 patches wide. You could color it yellow while you're testing, and change it to hidden when you're sure it is working. If a turtle is on that patch, it has crossed the line. If you make it wide enough it should be impossible to leap over at any speed. It should be easy to test using only one turtle and running the model slowly.
To count stopped cars:
Without seeing your code it's hard to tell why you are counting stopped cars twice. Can you post your code or the relevant section of it here? I'm guessing you have some global that you are incrementing each time you find a new stopped car.
It's less efficient, but much more reliable to let the cars own a variable like "stopped?" that you initialize to false and set to true when the car crosses the line. Then at any time you can get the accurate count of stopped cars with
count cars with [ stopped? = true ]
Assuming you have a variable called my-count of stopped cars, and you want to see when that goes wrong, you could insert a line of code like
if mycount != count cars with [stopped? = true] [user-message "count is wrong!"]
If the line is definitely going to be vertical (as in your diagram) then the easiest way may be simply to count the turtles with pxcor larger than whatever coordinate the line is at plus something for the car size.
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
I am trying to make turtles move along fixed paths that the user can draw in the u.i. The forward command can make turtles move a certain fraction of a patch forward per tick I assume, however to instigate smooth movement would it be possible to specify a fixed movement per tick in the setup commands for turtles? If this is possible what would be the basic structuring of the code I would use to achieve this?
The fd command (bk as well) accept floating-point inputs. I.e.
Ask turtles [ fd .01 ]
Makes each turtle move forward 1/100th of a patch. This movement happens at the time of the command.
Tick does not have any connection to when commands are carried out. If you set view updates to on ticks it can effect when you see updates otherwise it is usually a scheme for keeping track of how many times go has run.
A sample model of turtles moving at different speeds.
Turtles-own [speed]
To setup
Crt 100[
Set speed random-float 1
]
End
To go
Ask turtles[ rt 1 fd speed]
End
Copy and paste that into a new model make setup and go buttons. Mess with it for a while.