How do I report distance from patch to turtle in behavior space? - distance

I have patches in a circle that represent something that the turtles go into. In the end when running Behavior Space experiments I want to be able to measure the distance from each turtle to the edge of that circle, and I want to report the net value of it. I keep getting errors and I do not know properly how to do it.
I've tried setting final coordinates and initial coordinates to "patch-here". But I keep getting problems that say "You can't use INITIAL-COORD in an observer context, because INITIAL-COORD is turtle-only".
;my code ends at 350 ticks, this is in the go function...
if ticks = 350
[ask rbc [ set final-coord patch-here ]
ask initial-coord [set dist dist + distance final-coord]
set dist dist / (count rbc)]
;and then when I try to make a file from my data...
to makeOutputFile
set fileCounter 0
let date date-and-time
repeat 16 [set date remove-item 0 date]
set output_folder (word "Experiments/")
while [file-exists? (word output_folder"run_"fileCounter"_"date"_output.txt")][set fileCounter fileCounter + 1]
let output_file(word output_folder"run_"fileCounter"_"date"_output.txt")
file-close-all
file-open output_file
file-write ( "dist:")
file-write (dist)
end

try replacing:
[ask rbc [ set final-coord patch-here ]
ask initial-coord [set dist dist + distance final-coord]
set dist dist / (count rbc)]
with:
set dist mean [distance initial-coord] of rbc
This should work if inital-coord is a global or turtle property
Also, you might calculate this in the "measure runs using these reporters" area in the BehaviorSpace window instead of writing to files manually.

Related

How to add 1 to a variable after one tick?

I try to add a number (1) to a part of the turtles after a tick. The function should always add one to the variable after one tick but currently, the function adds it only one time - after the first tick and then stops. The variable "updated_prob" is currently not steadily updated.
This is how the Goprocess looks like
to go
ask turtles[
ifelse (color = grey)
[update_update_prob]
[e-bikenutzung]]
tick
end
to e-bikenutzung
ask turtles with [color = green]
[if ticks = 48
[set color grey
set ebike? false
set probability_ebike_start 50]]
end
to update_update_prob
ask turtles with [color = grey]
[set prob_sum probability_ebike_start + environment_add + subventionierung_bonus]
ask turtles with [color = grey]
[set updated_prob prob_sum + 1] ------- is not steadily updated
end
Is there a typo in your code? The statement
set updated_prob prob_sum + 1
adds 1 to prob_sum, not to updated_prob and if prob_sum doesn't change from tick to tick, neither will updated_prob. Do you want
set updated_prob updated_prob + 1
instead?
Your code also has a lot of redundancies. If update_update_prob is executed only for grey turtles, then you don't need in update_update_prob to ask only gray turtles to do what you are doing in that procedure. Only gray turtles will execute it anyway. With lots of turtles, that can add a lot of overhead.
to update_update_prob
[set prob_sum probability_ebike_start + environment_add + subventionierung_bonus]
[set updated_prob updated_prob + 1]
end
should do it.

select all patches at distance x from turtle

I want to select all the patches at a randomly-generated distance eps from all turtles in a simulation and reset their color to yellow. This essentially draws a circle of patches around each turtle in the simulation. I have tried a few different options without success. Through perusing this forum I found some code that looks promising but still has some issues (posted here). I appreciate any suggestions for tweaking this code or using something else to solve this problem.
let eps2 eps
foreach [ eps2 ]
[
ask patches with
[
distance myself > eps2 - 0.5 and
distance myself < eps2 + 0.5
]
[
set pcolor yellow
]
]
eps is a turtle variable so using the let command allows me to circumvent using a turtle variable in patch context.
The foreach command does not recognize eps because it is not a constant, is there another command I could use here?
You can use list (see below), but ... why do you want a list? As it stands, there is no need to use a list.
to setup
ca
crt 1
ask turtle 0 [test]
end
to test
let eps2 10
foreach (list eps2 ) ;you can use `list`
[
ask patches with
[
distance myself > eps2 - 0.5 and
distance myself < eps2 + 0.5
]
[
set pcolor yellow
]
]
end
Addendum:
Since you indicate that you do not in fact need that list, you might try something along the lines of the following:
to test2
ca
crt 1
ask encirclingPatches turtle 0 10 1 [set pcolor yellow]
end
to-report encirclingPatches [#t #dist #width]
let _w2 (#width / 2)
report patches with [
distance #t > #dist - _w2
and
distance #t < #dist + _w2
]
end

Storing agent coordinates in a list in NetLogo

I'm trying to create a simple simulation of agents moving randomly but avoiding certain obstacles. I want them to store the coordinates of the places they've been so they don't go there again. This is part of what I have so far:
to move-agent
let move random 3
if (move = 0) []
if (move = 1)[ left-turn ]
if (move = 2)[ right-turn ]
set xint int xcor ;;here i'm storing the coordinates as integers
set yint int ycor
set xylist (xint) (yint)
go-forward
end
to xy_list
set xy_list []
set xy_list fput 0 xy_list ;;populating new list with 0
end
However, it keeps giving me a "SET expected 2 inputs" error. Can anyone help me with this?
It looks like you are incorrectly using xy_list as both a variable and a turtle variable.
I don't see the need for the xy_list procedure - Keep it as a turtle variable. Make sure xy_list is in the turtles-own list:
turtles-own [xy_list]
initialize it to an empty list when you create a turtle. eg:
crt 1 [set xy_list []]
When a turtle moves, you could add their current position as an xcor, ycor list with:
set xy_list fput (list int xcor int ycor) xy_list
You will then need to check if that coordinate already exists in the list before moving there.
However, as you are using integer coordinates, it would be a lot easier to use a patch-set to keep track of a turtle's history. You could try this:
turtles-own [history]
to setup
ca
crt 3 [set history (patch-set patch-here) pd]
end
to go
ask turtles [
let candidates neighbors with [not member? self [history] of myself]
ifelse any? candidates
[move-to one-of candidates stamp
set history (patch-set history patch-here)]
[die]
]
end

Netlogo: measure mean distance between start and end patches

I am teaching myself how to create ABMs in Netlogo using the book of Railsback & Grimm 2012. I am having trouble with one book exercise which is on butterflies following "virtual" corridors. Basic idea is that butterflies go uphill for mating using the differences in height as guide. I need to calculate the width of the corridors dividing the number of patches used by the butterflies over the average distance the butterflies fly from the start patch to the end patch. I am
struggling with plotting this corridor width, which I am coding like this:
to-report corridor-width
let patches-visited count patches with [used?]
let mean-distance mean [distance start-patch] of turtles
report patches-visited / mean-distance
I then created a plot in the interface with the command:
plot corridor-width
The error message I get reads:
Division by zero. error while observer running / called by procedure
CORRIDOR-WIDTH called by plot 'Corridor width' pen 'default' update
code called by procedure SETUP called by Button 'setup'
I believe there is something wrong with the way I am coding distance start-patch but I have surfed the web and looked at several codes and I cannot spot my mistake. My whole code looks like this:
globals [ q ] ;; q is the probability that butterfly moves directly to highest patch
turtles-own [ start-patch ]
patches-own [ elevation used? ] ;; patches property of elevation and whether the patch has been used by butterfly or not.
to setup
ca
;; Let's create patches and asign them an elevation and color by using ask patches statement
ask patches
[
;; Elevation decreases linearly with distance from the center of hills. Hills are at (30,30) and
;; (120,120) coordinates. The first hill is 100 units high whereas the second one is 50
let elev1 100 - distancexy 30 30
let elev2 50 - distancexy 120 100
ifelse elev1 > elev2
[ set elevation elev1 ]
[ set elevation elev2 ]
set pcolor scale-color green elevation 0 100
set used? false
]
;; Create 50 butterflies
crt 50
ask turtles [
set size 6
;; set their initial location as their initial patch
setxy random-pxcor random-pycor
set start-patch patch-here
;; have the butterfly draw its path with the pen-down statement
pen-down
]
reset-ticks
;; Initialize the q parameter
set q 0.4
end
;; The master schedule
to go
ask turtles [ move ]
plot corridor-width
tick
if ticks >= 1000
[
let final-corridor-width corridor-width
write "Corridor width: " print final-corridor-width
;export-plot "Corridor width" (word "Corridor-width-output-for-q-" q ".csv")
stop
]
end
;; let's code the butterfly procedure of movement
to move
if elevation >=
[ elevation ] of max-one-of neighbors [ elevation ]
[ stop ]
ifelse random-float 1 < q ;; Decide whether to move to the highest sorrounding
;; patch with p=q
[ uphill elevation ] ;; move deterministically uphill
[ move-to one-of neighbors ] ;; or move randomly
set used? true
end
to-report corridor-width
let patches-visited count patches with [used?]
let mean-distance mean [distance start-patch] of turtles
report patches-visited / mean-distance
end
What happens when the mean-distance is 0?
let mean-distance mean [distance start-patch] of turtles
Essentially, in your setup, you set all the turtle's start-patch to their current patch. So, if you ask all the turtles how far away they are from their start patch, they will all tell you 0 units away.
So, [distance start-patch] of turtles is filled with a list of all 0's.
Thus, a mean of a list of all 0s is 0 causing your divide by 0 error.
Maybe in this situation, you want to report 0 instead...so
ifelse mean-distance = 0
[ report 0]
[report patches-visited / mean-distance]

NetLogo: How to pull coordinates from neighboring patches based on patch-variable

I have limited programming experience (mechanical engineering student, so a bit of matlab and labview experience) and am very new to NetLogo, so I apologize in advance if this question is pretty basic or my code is of poor quality.
I need to have my turtles move to 1 of 2 possible neighboring patches based on a given probability function. The two patches that I need to input to the probability function are the two neighboring patches with the lowest nest-scent value. I have been able to pull the two lowest nest-scent values, but I cannot figure out how to actually figure out which patches those are, and how to put those coordinates into an ifelse statement to move the turtle to one of them based on the aformentioned probability function. I have the following code that is obviously not working:
to move
set farthest-patch sort-by < [nest-scent] of neighbors
let a1x pxcor of item 0 farthest-patch
let a1y pycor of item 0 farthest-patch
let a2x pxcor of item 1 farthest-patch
let a2y pycor of item 1 farthest-patch
let a1 item 0 farthest-patch
let a2 item 1 farthest-patch
let x (((a1 + a2) / 100 ) - 1)
let probability-move 0.5 * (1 + ((exp(x) - exp( - x)) / (exp(x) + exp( - x))))
ifelse random-float 1 < probability-move
[set to-move 1]
[set to-move 0]
let a1-probability (a1 / (a1 + a2))
ifelse random-float 1 < a1-probability
[set destination [a1x a1y]]
[set destination [a2x a2y]]
ifelse count turtles-here >= 20
[set full 1]
[set full 0]
if [a1x a21] = full
[set destination [a2x a2y]]
if [a2x a2y] = full
[set destination [a1x a1y]]
if [a2x a2y] and [a1x a1y] = full
[set to-move 0]
ifelse to-move = 1
[move-to destination]
[stop]
end
Basically what I have (tried) to do here is sort a farthest-patches list by increasing nest-scent, and I have pulled the two lowest nest-scent values in order to input those values into my probability functions (both for whether or not to move, and if they are to move which of the two patches to select). I am not sure how to properly pull the patch coordinates of the patches that the a1 and a2 values were taken from.
Thanks for any help,
Brad
okay, you are making life way more complicated than it needs to be. You can select the two patches (or turtles) with the smallest values of a variable with min-n-of. Look it up in the dictionary to get the details.
Having found the two candidates, the best option is to use the rnd extension for choosing the destination because it has a primitive for random selection by weight. Finally, since you are using a function of your variable as the weight (rather than the variable value itself), you need a way to construct that weight. The best option is to separate it out - you could also have a second variable with the weight value, but that just proliferates variables.
Here is a complete working model. Please copy the whole thing into a new instance of NetLogo and try and understand how it works, rather than just copy the relevant bits into your code because min-n-of, using agentsets and passing variables to procedures are important aspects of NetLogo that you need to know about. I have also set up colouring etc so you can see the choices it makes.
extensions [rnd]
patches-own [ nest-scent ]
to setup
clear-all
create-turtles 1 [ set color red ]
ask patches
[ set nest-scent random 100
set plabel nest-scent
]
reset-ticks
end
to go
ask one-of turtles [ move ]
tick
end
to move
set pcolor blue
let targets min-n-of 2 neighbors [ nest-scent ]
let destination rnd:weighted-one-of targets [ calc-weight nest-scent ]
move-to destination
end
to-report calc-weight [ XX ]
let weight 0.5 * (1 + ((exp(XX) - exp( - XX)) / (exp(XX) + exp( - XX))))
report weight
end