Multiple statements in ask - netlogo

Is is allowed to use multiple statements in an ask command. I ask this because my agents do not count their lost variable in a correct way. Slider-s is zero and slider is 10.
[ ask smaller [ set heading [ heading ] of larger forward 0.05 set lost lost + 1 set lostcount lostcount + 1 set color [color] of larger
if random 100 < slider-s [ if lost > random 100 [ set heading random 360 set lost 0 set color random-float 100]]]]
[ if random 100 < slider
[ ask larger [ set heading [ heading ] of smaller forward 0.05 set lost lost + 1 set lostcount lostcount + 1 set color [color] of smaller
if random 100 < slider-s [ if lost > random 100 [ set heading random 360 set lost 0 set color random-float 100]]]]]

yes, it is valid to have multiple commands within an ask block. It is also valid to have multiple statements on a single row (though somewhat unreadable). If it wasn't valid, the green tick syntax checker would throw a yellow highlighted error message.
<whatever is the line before - presumably ask some agentset>
[ ask smaller
[ set heading [ heading ] of larger
forward 0.05
set lost lost + 1
set lostcount lostcount + 1
set color [color] of larger
if random 100 < slider-s
[ if lost > random 100
[ set heading random 360
set lost 0
set color random-float 100
]
]
]
]
[ if random 100 < slider
...
]
]
If you use indenting as above, your code takes more lines but it is easier to pick up some types of errors. In particular, is it possible that your code is miscounting the lost variable because the bracketing is incorrect and some agents are passing through these nested loops an incorrect number of times?

Related

Netlogo: resetting event every tick, but tick counter goes on

Trying to let a flood appear with every tick and make it disappear after every tick as well. Meanwhile, the tick counter should go on.
The flood appears this way:
to water_rise
ask patches [ ; saturates cell
if is-DEM < 800[
set cell-storage cell-storage + fill-rate
]
]
ask patches [
if any? neighbors4 with [ any? turtles-here ] [
set cell-storage cell-storage + fill-rate
]
]
ask patches [
if cell-storage > 0 [
if cell-storage > 5 [
set cell-storage 5
if not any? turtles-here [
sprout 1 [
set color blue
set size 10
set shape "circle"
]
]
]
set pcolor cell-storage + 82
]
]
end
Currently trying to figure out how to let the flood disappear after/or within this the tick, so that it can reoccur in the next one. I´m not aiming to reset the tick counter, it should reach 200.
Tried resetting the ticks, but only to manage resetting everything.
Any ideas ?
Thank you very much in adavance
Cheers
You can simply use the display primitive to update the view without waiting for the tick counter to advance.
I am not familiar with your whole model but here's a conceptual example that may help:
to water_rise
...
end
to go
repeat 100 [
water-rise
display
]
tick
end
This code would execute your water-rise procedure 100 times, update the view with new patch colors after each execution, and only increase the tick counter by 1 after the repeat loop is done.
Here is the link to NetLogo Dictionary entry about the display primitive:
http://ccl.northwestern.edu/netlogo/docs/dictionary.html#display
Note: due to its design, NetLogoWeb does not support the display primitive. So, you need to use the desktop version.

What is the most appropriate way to include randomness in the movement - NetLogo

First, let me describe what I am doing and why I am asking this question.
I have 74 cities included in the model and I want to simulate movement between them. I have an OD probability matrix where rows are origins and columns are destinations. Matrix looks like this:
0 1 ..... 73
----------------------
0 |0.5 0.1 .... 0.0
...| . . .. . .
73 | 0.1 0.2 .. 0.3
Please note: if we look at the first row, that means that an agent from the city with index 0 has the probability to stay in it 0.5, to move to the city with idx=1 0.1 and so on.. What I want to do is to on the best statistically speaking way distribute agents' destination. For the agents which origin is city 0 I want to stay approximately 50% of agents (not exact 50%), but also I want to give some chance to the cities that have 0% probability, like pair 0-73.
I already coded the randomness according to the answer to this question: Netlogo: How can send agents from "area x" to "area y" using an O/D matrix?
But the answer for me in this question is not logical, concretely this part:
ask turtles with [residency = "nw"]
[ let myrandom random-float 1
ifelse myrandom <= 0.5 [ set destination "nw" ] [
ifelse myrandom <= 0.8 [ set destination "ne" ] [
ifelse myrandom <= 0.0 [ set destination "sw" ] [
set destination "se" ]]]
If I understood well, myrandom would take a value in the range 0-1 and then it would go to check one by one condition whether its' value is smaller or equal than this constant values.
In that sense, myrandom wound never get to the "sw" part (0 would always be smaller than 0.5) and there is more chance to get the "nw" part where probability is 0.5 than the "ne" part where the probability is higher-0.8. And only because it's not listed first. I am no sure that this is the right way to go, and also I am not sure which is (I can't sort my probabilities because their position represents city-id(see below)). Or I understood wrong?
Here is presented the part of my code. I imported the matrix without the headings/cities ID because they are equivalent to NetLogo indexing. The cities with ID are already imported into the model. Also, in each point/city I created the corresponding number of agents that I read for each city from the CSV file. During the creation of the agents, I use the row from the matrix that corresponds to the current city/origin and go through the probabilities as JenB did in his answer above.
breed [city cities]
breed [inhabitant inhabitants]
;; part of the setup
;; open the csv file that contains population per city
file-open path
while [ not file-at-end? ] [
let data csv:from-row file-read-line
let city-id item 0 data
let population item 1 data
to add-inhabitants
create-inhabitants population [
set city-home one-of cities with [id = city-id] ;; set the origin
move-to city-home
set-destination(city-id) ;; for this origin chose the destination
]
]
to set-destination [row] ;; row from the matrix which represent the movement from the current city/origin to other cities
let row-probabilities matrix:get-row od-matrix row ;; use the row that correspondents to the city
let random-value random-float 1
let i 0 ;; index counter
foreach row-probabilities [ ;; for each probability in row
p ->
if random-value <= p ;; this part is coded as in the JenB's answer
[
set destination one-of cities with [id = i] ;; i is column index which is actually index of destination city
stop ;; if you set city -> stop
]
if i = 73 [set destination one-of cities with [id = i]
stop] ;; the last city -> there is no more option/reason to check
set i i + 1
]
end
I know it's a little bit longer, but I wanted to explain clearly. Some guidelines and explanations would be much appreciated!
Your question suggests that you don't understand what the code in that section is doing. This is the corrected code for that bit:
ask turtles with [residency = "nw"]
[ let myrandom random-float 1
ifelse myrandom <= 0.5 [ set destination "nw" ] [
ifelse myrandom <= 0.8 [ set destination "ne" ] [
ifelse myrandom <= 0.9 [ set destination "sw" ] [
set destination "se" ]]]
Yes, the first line in the block draws a random number in the range 0 to 1. Imagine that the draw gave 0.4. Then the first ifelse would be true and the destination would be set to "nw". Now imagine the draw was 0.6, then the first ifelse would be false and the code would go on to test the else part, which is true because 0.6 <= 0.8.
The code works because the initial draw is uniform. That is, 10% of the time (on average) it returns a number in the range 0 to 0.1, and 10% in the range 0.1 to 0.2 and so on. So 50% of the time it returns a number in the range 0 to 0.5, which returns true for the first line. 30% of the time it returns a number in the range 0.5 to 0.8, which is false for the first test and true for the second test. 10% of the time it returns a number in the range 0.8 to 0.9 and 10% of the time it returns a number in the range 0.9 to 1.
So breaking the interval with check points at 0.5, 0.8, 0.9 (and 1 for the remainder) gives you sections that are 0.5, 0.3 (=0.8-0.5), 0.1 (=0.9-0.8) and 0.1 (=1=0.9) in length. And a uniform random number will fall into those sections with probability distribution 50%, 30%, 10% and 10% of the draws.

Variables in different breeds

i'm trying to make an archaeological model, in which hunters are making paintings in shelters, depending on their quality.
breed [shelters shelter]
breed [hunters hunter]
shelters-own [quality paintings]
The value of each shelter quality is set in the setup (with a slider for the actual number of shelters).
create-shelters number-shelters [set quality random 100]
The action of painting-or-not is then defined by random against the quality of each shelter:
to make-painting
ask shelters [
if any? hunters-on patch-here [
if random 100 < quality [set paintings paintings + 1]
]
]
end
Now, I would like to complexify it a bit more: the quality wouldn't be defined by the shelter itself (and thus be the same for every hunter), but by the hunters: each of them would attribute a different quality for each shelter. The action of painting-or-not would still be a test against random, but with this new variable defined by each individual hunter...
But I can't find a way to code it down properly.
Does anyone have a suggestion?
I think I got it right. Basically, I had every hunter to create a matrix filled with random numbers. The size is 33x33, so it goes all over the world (had to set it to start in a corner, or it gets negative coordinates).
create-hunters number-hunters [
set color white
set size 1
setxy random-xcor random-ycor
set hunter-matrix matrix:make-constant 33 33 random 10
]
ask n-of number-shelters patches [
sprout-shelters 1 [
set color one-of base-colors
set size 1
set xpatch xcor set ypatch ycor
]
Then, when they would reach a shelter, the value corresponding to that patch location would be extracted and used to paint-or-not.
ask patches [
ask hunters-here [set quality matrix:get hunter-matrix xpatch ypatch]
let paintings-here sum [paintings] of shelters-here
if any? hunters-here and any? shelters-here [
if random 10 < quality [
ask shelters-here [
set paintings paintings + 1]
]
]
]
I'm still not completely sure it actually does what I think it's doing, tho.

How do I properly use the 'random' function for multiple agents?

In my model I have some agents collecting from another agent who they bump into at random after which they move back to their base. As they move back they drop off some material as defined by the random function. Here's some sample code
to go
ask searchers
[ set energy energy - 1
fd 0.0125
if random-float 1 < (1 / 50)
[ ifelse random 2 = 0
[ rt 45 ]
[ lt 45 ]
]
search
]
end
to search
if any? depots in-radius vision with [color = yellow]
[spread
set energy 0] ;; makes them to back to base
end
to spread
if random 10000 = 1 [hatch-rubbish 1 [ set color white
set shape "circle"
set size 0.5]]
end
If I set the visual radius to something enormous so they can always see the depot the number of bits of rubbish works out.
However if I allow them to move around with a radius of 1, the count of rubbish is much higher than 1 in 10,000.
Why would that make a difference?
Thanks

Trying to get factions to arrange in segments? NetLogo code advice

I've made a model that aranges factions (turtles in different colours) in a circle.
At the moment they arrange randomly, was wondering if someone could help me arrange them so, for example, red occupies the first 90 degrees, blue the next 90 degrees, etc (on setup).
Here's my code...
ask patch 0 0
[ ask patches in-radius ( max-pxcor * .9) with [ random-float 100 < density ]
[ sprout 1
[ set breed cons
set shape "circle"
set faction random factions
set heading random 360
set size 1
]
]
]
.. guessing I will have to do 360 / fractions, but not sure how to phrase it, if someone could help me out that'd be great. Thanks!
The NetLogo primitive that's the closest to what you want to do is in-cone, which reports the set of turtles that are in the "cone of vision" of another turtle. But your "pie slices" should just be relative to patch 0 0, not to another turtle! No problem: just make a temporary turtle at patch 0 0, use it to get turtles in-cone with the appropriate angle, and kill your temporary turtle.
The following procedure can be used "as is" with your code (just call it from your setup procedure after creating your turtles exactly as you were doing before):
to assign-factions
let angle 360 / factions
foreach n-values factions [?] [
ask patch 0 0 [
sprout 1 [
set heading ? * angle
ask turtles in-cone max-pxcor angle [ set faction ? + 1 ]
die
]
]
]
end
The code is pretty straightforward, except for maybe the more obscure n-values. You could replace it with a while loop if you prefer, but it's really just counting from 0 to factions.
Here is what you'd get with 5 factions: