I have a few variables which can be inherited to child agents by a variation of + 0.1 and -0.1 or without any changes, or random again, What I have done is like this: (The code is just an example)
to reproduce
ask turtle 1
[
let X-Of-Mother X
hatch 1
[
set X one-of (list (X-Of-Mother) (X-Of-Mother + 0.1) (X-Of-Mother - 0.1) (random-float 1))
]
]
end
Currently I have to check if X of child turtle is always within range by something like this:
if X > 1 [set X X - 0.2]
if X < 0 [set X X + 0.2]
What could be a better way to do it?
What if I have to use random-normal 0.5 0.1 , how can I limit that to values between 0 and 1 , I have done many repetitions of generating such random numbers I think the quality of random-normal is good and there is not that many times that I need to check if it's beyond the range.
for example :
to test
Let c 0
let b 0
repeat 100000000
[Set b random-normal 0.5 0.1
if b > 1 [set C C + 1]
If b < 0 [set C C + 1]
]
print c
end
OUTPUT is *67 times out of 100000000 Time* 67 is biggest one I got, I got 58 , 51 , ...
To create a local variable, use the let command. If you use let at the top of a procedure, the variable will exist throughout the procedure. If you use it inside a set of square brackets, for example inside an “ask”, then it will exist only inside those brackets.
random-float is a mathematics primitive that reports a random floating point number anywhere between 0 and the given number. For instance, random-float 10 could report 6.9105, 7, 4.2, 0.451, 0.0000001, 9.99999, etc.
In both StarLogoT and NetLogo, commands are executed asynchronously; each turtle or patch does its list of commands as fast as it can.
As you've discovered, random-normal
can be problematic because the result you get back can be literally any number.
One possible solution is to clamp the output of random-normal
within boundaries, as in Matt's answer. Note that this approach creates spikes at the boundaries of the range:
observer> clear-plot set-plot-pen-interval 0.01 set-plot-x-range -0.1 1.1
observer> histogram n-values 1000000 [ median (list 0 (random-normal 0.5 0.2) 1) ]
Another possible solution, as Marzy describes in the question itself, is to discard any out-of-bounds results random-normal
gives you and just keeping trying again until you get an in-bounds result. This avoids the spikes at the boundaries:
to-report random-normal-in-bounds [mid dev mmin mmax]
let result random-normal mid dev
if result < mmin or result > mmax
[ report random-normal-in-bounds mid dev mmin mmax ]
report result
end
observer> clear-plot set-plot-pen-interval 0.01 set-plot-x-range -0.1 1.1
observer> histogram n-values 1000000 [ random-normal-in-bounds 0.5 0.2 0 1 ]
Another solution is to ask yourself whether you really need a bell curve, or whether a triangle-shaped distribution would be just fine. You can get a triangle-shaped distribution of results very simply just by summing two calls to random-float
:
observer> clear-plot set-plot-pen-interval 0.01 set-plot-x-range 0 1
observer> histogram n-values 10000000 [ 0.5 + random-float 0.5 - random-float 0.5 ]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With