Is it possible to import different files? - netlogo

First, I'm sorry if this is a dumb question as I am new to Netlogo.
I've done the butterfly model from Steven Railsback and Volker Grimm book and there is an exercise to import a file that has coordinates X Y and a variable which is elevation in that example. So far, OK. But i'm currently trying to implement a model in which we have 4 different files each one containing the same coordinates but different variables, my question is: Is it possible to import those 4 files and have 4 different variables in our 'environment'?

Just to make sure- you are working with the "ElevationData.txt" file found here, correct? So your file reading code should look more or less exactly as shown in the Railsback and Grimm book:
file-open "ElevationData.txt"
while [not file-at-end?] [
let next-X file-read
let next-Y file-read
let next-elevation file-read
ask patch next-X next-Y [set elevation next-elevation]
]
file-close
So if the other files you want to import are mostly identical to the "ElevationData.txt" file, but with a different value in the third column, you can absolutely just modify that chunk of code accordingly. If we are dealing with vegetation cover as an example, you'd need a patches-own variable for that, along with the elevation variable that already exists:
patches-own [ elevation veg-cover ]
Now pretend that you have a "VegetationData.txt" file that looks something like:
0 0 0.86
1 0 0.15
2 0 0.42
3 0 0.44
4 0 0.43
5 0 0.33
...
After you have run your elevation import, you could do the exact same thing but with vegetation:
file-open "VegetationData.txt"
while [not file-at-end?] [
let next-X file-read
let next-Y file-read
let next-veg-cover file-read
ask patch next-X next-Y [set veg-cover next-veg-cover]
]
file-close
Now your patches will have a value assigned to both their elevation and veg-cover variables.
That said, it would be better if possible to combine your input files and load them all together. If you have a combined Elevation and Vegetation text file that looks like:
0 0 532.4 0.86
1 0 529.3 0.15
2 0 526 0.42
3 0 520 0.44
4 0 519.5 0.43
5 0 519.3 0.33
...
In the combined dataset ("ComboData.txt"), you still have the x and y columns, but now column three is elevation and column four is vegetation cover. Now you can load everything at the same time by slightly modifying your import code:
file-open "ComboData.txt"
while [not file-at-end?] [
let next-X file-read
let next-Y file-read
let next-elev file-read
let next-veg-cover file-read
ask patch next-X next-Y [
set elevation next-elev
set veg-cover next-veg-cover
]
]
file-close

Related

Import turtles position from a file

Good morning:
I am currently working on a netlogo program where I have a file with the turtle coordinates and I need to import that file so each turtle adopts the position that it is in the file. The file is the following:
9.220967873876688 30.6518906113243
-11.68237910031844 -11.246301104888516
2.5642482677264593 -1.6456061198786152
24.89458409582633 22.473096145446608
33.714972669018216 -17.295603130774897
10.347090714821402 13.476191522153966
3.881957027308774 -18.70063134965679
-21.711570773095524 -25.038263308838506
-20.649763022691737 28.674828042635635
-5.107177490557619 21.26440747439797
-6.29157511915799 -32.595514274136164
19.134302620042213 -26.443694241313267
-27.207781014142487 -3.48941202705942
18.198639754306242 -9.202785605985115
-12.82510430838797 5.818222632445828
-28.761569626881588 13.521815467262908
34.93451881825029 -34.49959417879696
27.234341179357532 5.506201903765271
The first column is the x axis and the second column is the y axis. The world dimension is y axis (-35,35) and x axis (-35,35). In this example there are 20 coordinates. So I want to do an import from this file which generates 20 turtles placed according to the file coordinates.
Thank you for your help.
Assuming the coordinates file is a text file with values separated by spaces and carriage returns, as it seems from the question, the file-related primitives are enough.
There are two possible cases.
You know in advance how many turtles' coordinates there will be
In this case, just use file-open, file-read and file-close:
to setup
clear-all
file-open "coordinates.txt"
create-turtles 18 [
setxy file-read file-read
]
file-close
end
(note that your file example contains 18 pairs of coordinates, not 20)
You don't know in advance how many turtles' coordinates there will be
In this case, add a while loop using file-at-end?:
to setup
clear-all
file-open "coordinates.txt"
while [not file-at-end?] [
create-turtles 1 [
setxy file-read file-read
]
]
file-close
end

Divide regions accordingly to physical features

I'm working on a smaller project and got stuck on an issue, I'm not really sure if it's possible to solve it in NetLogo but I want to give StackOverflow a go!
I got a model that divides the world into different parts and randomly add physical features (such as rivers). If a feature goes through the whole region, I want it to separate the region and make into two regions. As an example, in the picture below, I want to separate the purple region into two unique regions accordingly to the physical feature (black).
The code I used to generate the picture above, can be found below.
to setup
ca
;Setting world.
resize-world 0 19 0 19
;Creating regions.
let x 5
let y 5
let col 45
while [y <= max-pycor + 1][
while [x <= max-pxcor + 1 ][
ask patches with [pxcor < x and pxcor >= x - 5 and pycor < y and pycor >= y - 5][
set pcolor col
]
set x x + 5
set col col + 10
]
set x 5
set y y + 5
]
;Generating physical features.
ask n-of 5 patches[ sprout 1[
set pcolor black]
]
let i 0
while [ i < (max-pycor * 2 )][
ask turtles [
fd 1
set pcolor black
ifelse (random 20 <= 1)
[
rt one-of [-90 0 90]
forward 1
]
[
fd 1
set pcolor black
fd 1
set pcolor black
]
set pcolor black
set i i + 1]
]
ask turtles [die]
end
My strategy for handling this is to realize that all we really need to do is "flood" a patch out by color and tag all the found adjacent patches, then repeat for any un-tagged, non-black patches until they are all done.
NetLogo does not have a "flood" command to get all patches adjacent to a patch meeting a criteria, so we make a special reporter of our own to handle it, patches-adjacent. Then it's just easy to ask those patches-adjacent to set their region to the currently chosen region.
I don't love this code, it's a little finicky and would be prone to infinite loops if tweaked incorrectly, but it should work. I bet there is a cleaner way to do this that I'm not thinking of at the moment.
; add a variable to track the different regions
; the default value will be `0` for each patch when `clear-all` is called
patches-own [ region ]
to set-regions
let current-region 1
; only act on non-black patches that haven't yet been assigned a region
let untagged patches with [ region = 0 and pcolor != black ]
while [any? untagged] [
ask one-of untagged [
ask patches-adjacent [
set region current-region
]
]
; update the region and the untagged patches we have left to process
set current-region current-region + 1
set untagged patches with [ region = 0 and pcolor != black ]
]
; this is just to get a view of the regions to quickly see if our code worked, it can be removed
ask patches [ set plabel region ]
end
to-report patches-adjacent
report patches-adjacent-ex (patch-set self) pcolor
end
to-report patches-adjacent-ex [found pc]
let newly-found neighbors4 with [ (not member? self found) and pcolor = pc and region = 0 and pcolor != black ]
set found (patch-set found newly-found)
ask newly-found [
; use recursion to find the patches adjacent to each newly-found one
; relying on updating the `found` agentset as we go to avoid duplicates
; or looping forwarder
set found (patches-adjacent-ex found pc)
]
report found
end
I solved this by using the Patch Clusters model that can be found in the NetLogo model library.

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

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: