How to write values in files for each turtle? - netlogo

How can I write values in files for each turtle ? For example, I have 100 turtles and I would like to write data specific to each turtle in 100 files. For the moment, my code writes data for all turtles in one file .txt:
to write-locations-to-file
file-open "/home/reduan/IBM/outputs.txt"
ask turtles [
file-print (word who " ; " xcor " ; " ycor " ; " color " ; " [pcolor] of patch-here "\r\n" ) ]
end
Thanks in advance for your help.

I'm not sure what it is exactly that you are having trouble with, but you can just open a different file for each turtle. In the example below, I used the who number to generate different file names, but you could use some other method, as long as all file names are unique.
to write-locations-to-files
ask turtles [
file-open (word "/home/reduan/IBM/outputs-" who ".txt")
file-print (word who " ; " xcor " ; " ycor " ; " color " ; " [pcolor] of patch-here "\r\n" )
file-close
]
end

Related

How to create a table to know which turtles visited each patch in the world?

I would like to remove a doubt and have some help.
I have a closed world of 600X600 patches. Each patch spawns a turtle (using the sprout command). Each turtle makes a series of moves and returns a value for its home patch. I would like to have the following result: know which turtle was in each patch in the world and export this result in table form in .csv
I created a list for this. But, NetLogo is running for a while and then it closes and doesn't finish the model. And so I think if I create a table it should work. The question is: will creating a table solve the problem of the model not running? And if so, how can I create a table by generating an output from that table in .csv? But, I haven't found a NetLogo command that I can create a table to adjust my code to.
Any tip is very welcome. I thank the attention
globals [ edge-size output-turtle-visits ]
patches-own [ turtle-visits ]
to setup
ca
random-seed 1
set edge-size 599
set-patch-size 1.2
resize-world 0 edge-size 0 edge-size
let pcolors []
set pcolors [ 85 95 ]
ask patches [ sprout 1 ]
ask patches [
set turtle-visits n-values count turtles [0]
set pcolor item (random 2) pcolors
]
reset-ticks
end
to go
ask turtles [
rt random 360
fd 1
]
ask patches [
foreach [who] of turtles-here [ id ->
let current-num-visits item id turtle-visits
set turtle-visits replace-item id turtle-visits (current-num-visits + 1)
]
]
end
to output
file-open ( output-turtle-visits )
file-print ( word "id_turtle;my_xcor;my_ycor;turtle_visits" )
foreach sort patches
[
t ->
ask t
[
file-print ( word self " ; " xcor " ; " ycor " ; " turtle-visits )
]
]
file-print "" ;; blank line
file-close
end

How to separate values from a list using commas in netlogo?

Situation: I have a code that exports turtle coordinates according to the code below:
to path
file-open (word fileName ".csv")
file-print (word self xcor " " ycor)
file-close
end
The result is something like:
(turtle 1)[1 1 1 1 1 2] [4 4 4 2 1 5]
Question: How can I export this same list, but with its items separated by commas?
From [1 2 1 1 1] to [1,2,1,1,1], for example.
Thanks in advance
If you are trying to process this in R or something after the fact, I'd recommend potentially reporting in long format (ie, each line indicates a turtle, a tick [or similar], and the coordinates)- I find it simpler to process.
To answer your actual question- one way would be to manually collapse each list of coordinates into a string separated by commas. For example, see the toy model below.
Simple setup:
extensions [csv]
globals [ test ]
turtles-own [ xcor-list ycor-list ]
to setup
ca
crt 10 [
set xcor-list []
set ycor-list []
]
repeat 5 [
ask turtles [
rt random 90 - 45
fd 1
set xcor-list lput pxcor xcor-list
set ycor-list lput pycor ycor-list
]
]
reset-ticks
end
This reporter is what's actually doing the work of collapsing the list into a simple string for output:
to-report collapse-string-list [str-list]
report reduce word ( sentence map [ str -> word str ", " ] but-last str-list last str-list )
end
And this chunk pulls the desired turtle variables into a list of lists, calls the collapse-string-list reporter on them, then exports to a csv:
to output-coord-file
let all-turtles sort turtles
; Pull coordinates from each turtle
let who-coord-list map [
current-turtle ->
(list
[who] of current-turtle
collapse-string-list [xcor-list] of current-turtle
collapse-string-list [ycor-list] of current-turtle
)] all-turtles
; Add headers
set who-coord-list fput ["who" "x" "y"] who-coord-list
; Export
csv:to-file "toy.csv" (map [ row -> (map [i -> (word i)] row ) ] who-coord-list)
end
Output:

sensitivity analysis (mean of multiple simulations) in netlogo

I have several indexes such as mean and standard deviation of variables.
After 500 ticks, the model stops.
I want to simulate this model, for instance, 100 times and plot the mean and CI of indexes.
Instead of using python or R, is there any way to do this in netlogo?
Yes, you can use BehaviorSpace to run your model 100 times, saving the results you want to a file-system file, then have a different netlogo program ( or proocedure ) read in the data and plot it. Here's a sample writing part that computes mean and standard deviation of a run of numbers and after ten ticks stops.
globals [ delist demean destd fname ]
to setup
clear-all
set fname "myfile.txt"
set delist []
reset-ticks
end
to go
if ( ticks >= 10 ) [
;; show delist
set demean mean delist;
set destd standard-deviation delist;
export-data
;;print (word "mean = " demean " stdev= " destd )
stop
]
set delist lput random 100 delist
tick
end
to export-data
if not (file-exists? fname ) [
file-open fname
file-print ( word "mean stdev" );
file-flush
file-close
]
file-open fname
file-print ( word demean " " destd )
file-flush
file-close
end
to clear-file
if (file-exists? fname ) [
file-delete fname
]
end
here's sample code reading the above myfile.txt in and plotting it.
Assume a plot widget reporting demean and destd
globals [ delist demean destd fname ]
to setup
clear-all
set fname "myfile.txt"
print " This file begins as follows:"
set delist []
ifelse (file-exists? fname ) [
file-open fname
if not file-at-end?
[ let str file-read-line
print str
]
]
[ print " expected file doesn't exits " ]
reset-ticks
end
to go
if file-at-end? [ print "Data has been all read." file-close stop]
set demean file-read
set destd file-read
print (word "mean = " demean " , std-dev = " destd )
tick
end

Adding attributes to items of a list

I would like to know how to add attributes for each element of a list.
In particular, I have a list made by adding items at each tick. Each item has two attributes. These attributes are important to me, as I want to select an item based on the value of its attribute.
I did something like this:
ask one-of turtles ;; turtles have cars
[ set attribute_1 ;; cars' attribute
set attribute_2 ;; cars' attribute
set mylist fput car mylist
]
I would like something like this [car1 attribute_1 attribute_2, car2 attribute_1 attribute_2, car3...].
At the moment I have [car1 car2 car3...].
Once associated the attributes to the items, I would need to pick the item with highest value from the list. The user Omarito provided me a possible solution: How to select the item with highest value in a list, but it is not completely clear to me how to pick an item up.
What I would like to ask you is if it is possible to have something like [car1 attribute_1 attribute_2, car2 attribute_1 attribute_2, car3...] or if I can only have something like
[car1 car2 car3...]
or
[[attribute_1 attribute_2] [attribute_1 attribute_2] ...].
If I write set mylist fput [(list attribute_1 attribute_2)], I receive the error message: expected a literal value.
I hope you can help me. Thanks
UPDATE: After Nicolas' answer, I edited the code as follows:
ask one-of turtles
[
hatch-cars 1[ ;; buy a new car
set attribute_1 random-float 1
set attribute_2 random-float 1
]
let this-car self
set my-list fput this-car my-list
; ask turtles [show my-list]
set new_car? true
set old_car? false
set new_car new_car + 1 ;; how could I update it after the change?
]
Am I missing something?
There are many ways to approach this problem, but I will just give you two.
Let's start with the one closest to the way you're currently trying to do things.
turtles-own [ my-list ]
to setup
clear-all
create-turtles 3 [
set my-list [] ; start with empty list
foreach range 5 [ car -> ; let's pretend cars are just numbers
let attribute-1 precision (random-float 1) 2
let attribute-2 precision (random-float 1) 2
set my-list fput (list car attribute-1 attribute-2) my-list
]
]
ask turtles [
show my-list
print " Best car by attribute 1:"
let best-by-1 last sort-by [ [a b] -> item 1 a < item 1 b ] my-list
print word " Sublist: " best-by-1
print word " Car number: " item 0 best-by-1
print " Best car by attribute 2:"
let best-by-2 last sort-by [ [a b] -> item 2 a < item 2 b ] my-list
print word " Sublist: " best-by-2
print word " Car number: " item 0 best-by-2
print "--------"
]
end
Most of this code is for creating the turtles and displaying the result, but the two key lines are:
set my-list fput (list car attribute-1 attribute-2) my-list
for adding sublists to the main list, and:
let best-by-1 last sort-by [ [a b] -> item 1 a < item 1 b ] my-list
for sorting the main list by a specific attribute taken from the sublist. You can then use item 0 best-by-1 to get the car itself.
That being said, if you want to use NetLogo to its full potential, you should probably create a car breed:
breed [ cars car ]
cars-own [
attribute-1
attribute-2
]
breed [ agents an-agent ]
agents-own [ my-list ]
to setup
clear-all
create-agents 3 [
set my-list [] ; start with empty list
hatch-cars 5 [
set attribute-1 precision (random-float 1) 2
set attribute-2 precision (random-float 1) 2
let this-car self
ask myself [ set my-list fput this-car my-list ]
]
]
ask agents [
show my-list
print " Best car by attribute 1:"
let best-by-1 max-one-of turtle-set my-list [ attribute-1 ]
print (word " " best-by-1 ", attribute-1 = " [ attribute-1 ] of best-by-1)
print " Best car by attribute 2:"
let best-by-2 max-one-of turtle-set my-list [ attribute-2 ]
print (word " " best-by-2 ", attribute-1 = " [ attribute-2 ] of best-by-2)
]
end
The max-one-of primitive makes it easy to pick the best car and everything else will also probably be easier if you're working with agents instead of lists.

Netlogo: Create/ iterate multiple lists simultaneously

I have a simple Astar search model that finds the optimal path to a given destination. It operates on all turtles- however, it does so one at a time. I would like to speed up my simulation when having multiple turtles (ships) by having all turtles create/iterate through the search space (find-a-path) at the same time.
Below I have attached a portion of code where i call this. Is there a way I can modify my current code to support this? Any help would be greatly appreciated, thanks.
to find-shortest-path-to-destination
place-turtles
label-destination
ask ships
[
set path find-a-path current-waypoint target-waypoint
set optimal-path path
set current-path path
output-show (word "Shortest Path Length: " length optimal-path " (" "LP: " land-prox "," " LPW: " land-prox-weight ")")
]
end
to-report find-a-path [ source-patch destination-patch]
; initialize all variables to default values
let search-done? false
let search-path []
let current-patch 0
set open []
set closed []
; add source patch in the open list
set open lput source-patch open
; loop until we reach the destination or the open list becomes empty
while [ search-done? != true]
[
ifelse length open != 0
[
; sort the patches in open list in increasing order of their f() values
set open sort-by [[f] of ?1 < [f] of ?2] open
; take the first patch in the open list
; as the current patch (which is currently being explored (n))
; and remove it from the open list
set current-patch item 0 open
set open remove-item 0 open
; add the current patch to the closed list
set closed lput current-patch closed
; explore the neighbours of the current patch
ask current-patch
[
; if any of the neighbours is the destination stop the search process
ifelse any? neighbors with [ (pxcor = [ pxcor ] of destination-patch) and (pycor = [pycor] of destination-patch)]
[
set search-done? true
]
[
; the neighbors should not be obstacles or already explored patches (part of the closed list)
ask neighbors with [ elev <= min-depth and (not member? self closed) and (self != parent-patch) ]
[
; the neighbors to be explored should also not be the source or
; destination patches or already a part of the open list (unexplored patches list)
if not member? self open and self != source-patch and self != destination-patch
[
set pcolor gray + 1
; add the eligible patch to the open list
set open lput self open
; update the path finding variables of the eligible patch
set parent-patch current-patch
set g [g] of parent-patch + 1
set h distance destination-patch
set f (g + h)
]
]
]
if self != source-patch
[
]
]
]
[
; if a path is not found (search is incomplete) and the open list is exhausted
; display a user message and report an empty search path list.
user-message( "A path from the source to the destination does not exist." )
report []
]
]
; if a path is found (search completed) add the current patch
; (node adjacent to the destination) to the search path.
set search-path lput current-patch search-path
; trace the search path from the current patch
; all the way to the source patch using the parent patch
; variable which was set during the search for every patch that was explored
let temp first search-path
while [ temp != source-patch ]
[
ask temp
[
set pcolor white
]
set search-path lput [parent-patch] of temp search-path
set temp [parent-patch] of temp
]
; add the destination patch to the front of the search path
set search-path fput destination-patch search-path
; reverse the search path so that it starts from a patch adjacent to the
; source patch and ends at the destination patch
set search-path reverse search-path
; report the search path
report search-path
end