How to speed up the creation of turtles by classes of a map using NetLogo 6.2? - netlogo

I have a problem with accelerating a code in NetLogo. I tried a few things and they didn't work. The problem is in the "setup-patches" procedure that refers to the creation of turtles (please, see the code).
I have a map (I use the GIS extension, but to be a replicable example I didn't use it here) with 7 classes (which in the code is called habitatcover). 6 habitatcover have vegetation and therefore is used by turtles (mobile agent) and 1 class has no vegetation and therefore is not used by turtles (habitatcover 7). Turtles can born in the 6 types of habitatcover that have vegetation and their combinations result in 63 items (please, see the variable in the code called ValidHabs).
Also, I have 3 types of metabolism and 3 types of reproduction, which results in 9 combinations, that is, 9 types of turtles.
For each ValidHabs item (which has a total of 63 items) 50 individuals of each of the 9 types of turtles are born. Therefore, for item 0 of ValidHabs which is [1] 450 individuals will be born (= 9 * 50) it executes all the procedures and goes to the next item in the ValidHabs list until it goes through all the items in this list.
The problem is that as the world is 1000x1000 and 450 turtles are born per list item (which has 63 items in total), using GIS, as well, I have several maps to perform these procedures, in addition to having minimum 15 repetitions per map (using BehaviourSpace) takes a lot of time do execute one map (almost 5 days per map). I've already tried to make modifications to speed it up and haven't had much success. I know the problem is in the "setup-patches" procedure, but I'm not quite sure how to solve it. Can anybody help me?
Thanks in advance!
The code below:
globals
[
RandomSeeds
HotPatchSet
ValidHabs
ValidHabsItem
CurrentHotPatchSet
]
turtles-own
[
turtle-profiles-habitat
energy-reproduction
turtle-metabolism
turtle-profiles-code
turtle-profiles-reproduction-code
turtle-profiles-metabolism-code
turtle-profiles-habitat-code
]
patches-own
[
habitatcover
]
to setup
clear-all
set RandomSeeds 1
random-seed RandomSeeds
resize-world 999 * 0 ( 999 * 1 ) ( 999 * -1 ) 999 * 0 ;; defines the edge size of the world and location of origin: corner top left. The world is 1000x1000
read-legal-habs ;; create list of valid habitats for each turtle profile
set ValidHabsItem 0
setup-layers
setup-patches
reset-ticks
end
to read-legal-habs ;; create list of valid habitats for each turtle profile
set ValidHabs [[1] [2] [3] [4] [5] [6] [1 2] [1 3] [1 4] [1 5] [1 6] [2 3] [2 4] [2 5] [2 6] [3 4] [3 5] [3 6] [4 5] [4 6] [5 6] [1 2 3] [1 2 4] [1 2 5] [1 2 6] [1 3 4] [1 3 5] [1 3 6] [1 4 5] [1 4 6] [1 5 6] [2 3 4] [2 3 5] [2 3 6] [2 4 5] [2 4 6] [2 5 6] [3 4 5] [3 4 6] [3 5 6] [4 5 6] [1 2 3 4] [1 2 3 5] [1 2 3 6] [1 2 4 5] [1 2 4 6] [1 2 5 6] [1 3 4 5] [1 3 4 6] [1 3 5 6] [1 4 5 6] [2 3 4 5] [2 3 4 6] [2 3 5 6] [2 4 5 6] [3 4 5 6] [1 2 3 4 5] [1 2 3 4 6] [1 2 3 5 6] [1 2 4 5 6] [1 3 4 5 6] [2 3 4 5 6] [1 2 3 4 5 6]]
end
to setup-layers ;; the original code I use GIS. And depending on how the class distributions (habitatcover) are on the map, it takes longer to create the turtles
let pcolors [ ]
set pcolors [ 25 65 23 53 105 10 2 ]
ask patches
[
set pcolor item ( random 7 ) pcolors
]
ask patches
[
if pcolor = 25 [ set habitatcover 1 ]
if pcolor = 65 [ set habitatcover 2 ]
if pcolor = 23 [ set habitatcover 3 ]
if pcolor = 53 [ set habitatcover 4 ]
if pcolor = 105 [ set habitatcover 5 ]
if pcolor = 10 [ set habitatcover 6 ]
if pcolor = 2 [ set habitatcover 7 ]
]
end
to setup-patches
let list1 ( list 2 4 8 ) ;; metabolism types
let list2 ( list 10 15 20 ) ;; reproduction types
let n0 count turtles
set HotPatchSet patches with [ ( habitatcover != 7 ) ] ;; referring to all 6 habitatcovers that have some type of vegetation removing habitatcover 7 that has no vegetation
set CurrentHotPatchSet HotPatchSet with [ habitatcover = one-of item ValidHabsItem ValidHabs ] ;; CurrentHotPatchSet will be the HotPatchSet with the current habitatcover ;; ValidHabsItem is the item that goes from 0 to 62 since there are 63 habitacover combinations (see the list ValidHabs has 63 items)
let s ( length list1 ) * ( length list2 ) * 50 ;; 50 individuals per profile = 3 * 3 * 50 = 450 turtles
while [ n0 < s ]
[
(
foreach list1
[
this-metabolism ->
foreach list2
[
this-reproduction ->
let c count CurrentHotPatchSet
if c = 0 [ stop ]
ask one-of CurrentHotPatchSet
[
sprout 1
[
set turtle-profiles-habitat item ValidHabsItem ValidHabs ;; I need the ValidHabsItem and turtle-profiles-habitat, because in the "go" procedure I'm calling each item (ValidHabsItem) from the ValidHabs list to execute all the procedures
set turtle-metabolism this-metabolism
set energy-reproduction this-reproduction
setup-turtles
]
set CurrentHotPatchSet CurrentHotPatchSet with [ not any? turtles in-radius 3 ] ;; each turtle must be a minimum distance of 3 patches and can't have more than one turtle in each patch
]
]
]
)
set n0 count turtles
]
end
to setup-turtles
set turtle-profiles-habitat-code reduce_list turtle-profiles-habitat
(
ifelse
turtle-metabolism = 2 [ set turtle-profiles-metabolism-code "_M1" ]
turtle-metabolism = 4 [ set turtle-profiles-metabolism-code "_M2" ]
turtle-metabolism = 6 [ set turtle-profiles-metabolism-code "_M3" ]
)
(
ifelse
energy-reproduction = 5 [ set turtle-profiles-reproduction-code "_R1" ]
energy-reproduction = 10 [ set turtle-profiles-reproduction-code "_R2" ]
energy-reproduction = 15 [ set turtle-profiles-reproduction-code "_R3" ]
)
set turtle-profiles-code ( word turtle-profiles-habitat-code turtle-profiles-reproduction-code turtle-profiles-metabolism-code )
end
to-report reduce_list [ a_list ]
report read-from-string word reduce word a_list ""
end

Opening note: In no way I am assuming that my suggestions are exhaustive, as other people might see other things to improve.
I intend this question to be exclusively on code, i.e. assuming that it is not addressing non-code options such as computer cluster etc.
Eliminate the time needed to upload GIS data
Importing GIS data in NetLogo is a lengthy process. You can get rid of this process by using export-world and import-world (see here and here). These commands will let you export to a file the current state of your NetLogo world, and then import into NetLogo that state from the file. You can perform the export once when the GIS data has been loaded (so that the GIS information is stored in patches) and store the file somewhere: this means that you won't need to upload GIS data again but will only need to perform import-world.
My personal suggestion is that you create a separate NetLogo file to do this: only in this separate file you will have the GIS extension's procedures and the export-world command. In the file with your main model, you will only have the import-world part.
Of course you will need to create a new/different file for each new/different set of GIS files you use.
Reduce the amount of times you need to perform import-world
Your model is quite big, so it might be the case that import-world too takes some time. You can adjust your code such that, when using BeahviorSpace, you will only have to run import-world once.
See here for some previous discussion.
The idea is that in your setup, instead of using clear-all (which would also clear all of that imported data which is stored inside patches), you manually clear everything apart from patches (i.e. you use clear-globals, clear-ticks, clear-turtles, clear-drawing, clear-all-plots and clear-output). This will allow you to check if the data has already been imported: if not, then it means that this is the first run and you need to use import-world; if yes, it means that patches already have that information stored and thus import-world needs not to be performed.
I don't know if in your model the patch variables coming from GIS (i.e. coming from import-world) might be changed during the simulation. If this is the case, it means that you need to store the initial state of these variables as a special patch variable, which will be used to reset the initial state when you do not use import-world.
Some code will make all of this clearer. For example, in case the GIS information imported through import-world is stored as a vegetation patch variable, you can create an initial-vegetation variable for this purpose:
patches-own [
initial-vegetation
vegetation
]
to setup
clear-globals
clear-ticks
clear-turtles
clear-drawing
clear-all-plots
clear-output
ifelse (all? patches [initial-vegetation = 0])
[import-world "initial-state.csv"]
[ask patches [set vegetation initial-vegetation]]
end
Otherwise, if in your model the variable of interest can never be changed (following my example: if vegetation never changes during the simulation...) things are even simpler:
patches-own [
vegetation
]
to setup
clear-globals
clear-ticks
clear-turtles
clear-drawing
clear-all-plots
clear-output
ifelse (all? patches [initial-vegetation = 0])
[import-world "initial-state.csv"]
[]
end
Looking at your setup-patches procedure, I don't see any code that is obviously inefficient.
(probably set n0 n0 + 1 would be faster than set n0 count turtles - but this is just for the sake of noting it, as it surely has a negligible effect).
Possible unintended aspects in your code? (1)
ValidHabsItem is used twice but it is never set to anything different than zero. In setup there is set ValidHabsItem 0 (anyway note that this is superflous, as zero is the default value), and the value of ValidHabsItem is never changed. I don't know if this is used in some other way in the full version of your code (e.g. if the value of ValidHabsItem iterates from 0 to 62) but note that, looking exclusively at the code in your question, this means that item ValidHabsItem ValidHabs is always [1]. Which in turn, looking at the two instances where you use it in setup-patches, means that:
The statement:
set CurrentHotPatchSet HotPatchSet with [habitatcover = one-of item ValidHabsItem ValidHabs]
is equivalent to:
set CurrentHotPatchSet HotPatchSet with [habitatcover = 1]
The statement:
set turtle-profiles-habitat item ValidHabsItem ValidHabs
is equivalent to:
set turtle-profiles-habitat [1]
Overall this means that, by using the code in your question, turtles will only be born on orange patches (those with habitatcover = 1) and they will only have turtle-profiles-habitat = [1]. Is this intended? Is it not? I am not sure, but it looks peculiar enough for me to point it out.
Possible unintended aspects in your code? (2)
Let's imagine that ValidHabsItem is not constantly 0 but it goes from 0 to 62, with the effect that item ValidHabsItem ValidHabs is always a different list containing a varying number of numbers.
What do you want your code to do when you write:
set CurrentHotPatchSet HotPatchSet with [habitatcover = one-of item ValidHabsItem ValidHabs]
?
If you want to check that habitatcover of patches is one of the values in the current list of habitats, then this is not what your code is doing.
Let's take an example: the current list being represented by item ValidHabsItem ValidHabs is [2 4 5].
The one-of item ValidHabsItem ValidHabs statement is literally one of [2 4 5]. Given that one-of is a random reporter, let's say that in this occasion it extracts the value of 4. This means that your:
set CurrentHotPatchSet HotPatchSet with [habitatcover = one-of item ValidHabsItem ValidHabs]
is
set CurrentHotPatchSet HotPatchSet with [habitatcover = 4]
even if item ValidHabsItem ValidHabs = [2 4 5]; with the result that all patches having habitatcover = 2 or habitatcover = 5 will be excluded.
If it is correct to say that this is not what you wanted, it means that what you are looking for is the member? reporter (see here):
set CurrentHotPatchSet HotPatchSet with [member? (habitatcover) (item ValidHabsItem ValidHabs)]
In the example where item ValidHabsItem ValidHabs = [2 4 5], the code above will set CurrentHotPatchSet as every patch having habitatcover as either 2, 4 or 5.

Related

How to make a turtle reproduce in the same patch type using hatch command in NetLogo 6.2?

I have 31 turtles profiles that can be born in combinations of 5 habitat types. Below:
profile 1 needs these types of habitats: [1]
profile 2 needs these types of habitats: [2]
profile 3 needs these types of habitats: [3]
profile 4 needs these types of habitats: [4]
profile 5 needs these types of habitats: [5]
profile 6 needs these types of habitats: [1 2]
profile 7 needs these types of habitats: [1 3]
profile 8 needs these types of habitats: [1 4]
profile 9 needs these types of habitats: [1 5]
profile 10 needs these types of habitats: [2 3]
profile 11 needs these types of habitats: [2 4]
profile 12 needs these types of habitats: [2 5]
profile 13 needs these types of habitats: [3 4]
profile 14 needs these types of habitats: [3 5]
profile 15 needs these types of habitats: [4 5]
profile 16 needs these types of habitats: [1 2 3]
profile 17 needs these types of habitats: [1 2 4]
profile 18 needs these types of habitats: [1 2 5]
profile 19 needs these types of habitats: [1 3 4]
profile 20 needs these types of habitats: [1 3 5]
profile 21 needs these types of habitats: [1 4 5]
profile 22 needs these types of habitats: [2 3 4]
profile 23 needs these types of habitats: [2 3 5]
profile 24 needs these types of habitats: [2 4 5]
profile 25 needs these types of habitats: [3 4 5]
profile 26 needs these types of habitats: [1 2 3 4]
profile 27 needs these types of habitats: [1 3 4 5]
profile 28 needs these types of habitats: [1 2 4 5]
profile 29 needs these types of habitats: [1 2 3 5]
profile 30 needs these types of habitats: [2 3 4 5]
profile 31 needs these types of habitats: [1 2 3 4 5]
That is, each turtle has its own profile and can only disperse to the same type of habitat in which it was born. So if at tick 0 it was only born in habitat type 1, it will only be able to disperse in type 1 habitat. The problem is that I am not able to make it so that when the turtles reproduce, they are born in their correct habitat! can anybody help me? Any kind of help I appreciate it.
Thanks in advance!
Below is a piece of code:
extensions [ csv ]
globals [ ValidHabs htypes PatchAvailable ]
turtles-own [ energy reproduction my-patches ]
patches-own [ a-energy metabolism ]
to setup
clear-all
read-habs
reset-ticks
end
to read-habs
set ValidHabs [ ]
repeat 32 [ set ValidHabs lput [ 0 0 0 0 0 ] ValidHabs ]
show ValidHabs
file-close
file-open "colony_profiles_habitat_constraints.csv" ;;it reads in the habitat constraints from the "colony_profiles_habitat_constraints.csv" file and builds a list of lists
let headers file-read-line
let profile 0
while [ not file-at-end? and profile < 31 ]
[
let nextline file-read-line
let mydata csv:from-row nextline
set profile item 0 mydata
let h1 item 1 mydata
let h2 item 2 mydata
let h3 item 3 mydata
let h4 item 4 mydata
let h5 item 5 mydata
set htypes [ ]
if ( h1 > 0 ) [ set htypes lput h1 htypes ]
if ( h2 > 0 ) [ set htypes lput h2 htypes ]
if ( h3 > 0 ) [ set htypes lput h3 htypes ]
if ( h4 > 0 ) [ set htypes lput h4 htypes ]
if ( h5 > 0 ) [ set htypes lput h5 htypes ]
]
end
to go
Metabolic
end
to Metabolic
ask turtles [
let z [ a-energy ] of patch-here
(
ifelse
metabolism = 2 [
set energy energy - 2 + z
if energy <= 8 [ die ]
(
ifelse
reproduction = 5 [
if energy >= 5 [ Dispersion ]
]
reproduction = 10 [
if energy >= 10 [ Dispersion ]
]
reproduction = 15 [
if energy >= 15 [ Dispersion ]
]
)
]
metabolism = 4 [
set energy energy - 4 + z
if energy <= 8 [ die ]
(
ifelse
reproduction = 5 [
if energy >= 5 [ Dispersion ]
]
reproduction = 10 [
if energy >= 10 [ Dispersion ]
]
reproduction = 15 [
if energy >= 15 [ Dispersion ]
]
)
]
metabolism = 6 [
set energy energy - 6 + z
if energy <= 8 [ die ]
(
ifelse
reproduction = 5 [
if energy >= 5 [ Dispersion ]
]
reproduction = 10 [
if energy >= 10 [ Dispersion ]
]
reproduction = 15 [
if energy >= 15 [ Dispersion ]
]
)
]
)
]
end
to Dispersion
let available-patch htypes with [ distance myself > 2 and distance myself < 5 and count turtles-here = 0 and not any? other turtles in-radius 2 ]
set PatchAvailable count available-patch
if PatchAvailable = 0 [ stop ]
let choose-patch one-of available-patch
let coordx [ pxcor ] of choose-patch
let coordy [ pycor ] of choose-patch
hatch 1 [ setxy coordx coordy ]
end

How to create multiple turtles in certain patches of the world quickly using NetLogo 6.2?

I'm trying to solve a problem of speed in creating turtles in the NetLogo world.
I have a model that has a world with a size of 600X600. I, too, have 31 turtle profiles (each turtle can only born in a specific habitatcover type or habitatcover set (see ValidHabs variable in the code). In the code, too, there are 2 variables that are metabolism with 2 levels (list1 in the code) and reproduction with 2 levels (list2 in the code). Also, I would like to have at least 200 turtles born in the world or more in this world.
The problem is that it is taking a long time for turtles to be born in the world. Have I already created a switch called Display? to speed up the creation of the turtles. I also set it to faster speed and it still takes a long time to create the turtles.
Does anyone know how I can speed up the creation of turtles based on my code?
I don't know what else to do to speed up the code... I appreciate any kind of help :)
Thanks in advance
The code below:
globals [ ValidHabs ValidHabsItem HotPatchSet CurrentHotPatchSet ]
patches-own [ habitatcover ]
turtles-own [ turtle-profiles-habitat metabolism reproduction all-code code-metabolism code-reproduction ]
to setup
clear-all
random-seed 1
;; ValidHabs are the habitat profiles of the turtles are all combinations of 5 types of habitatcover without repetition
set ValidHabs [[1] [2] [3] [4] [5] [1 2] [1 3] [1 4] [1 5] [2 3] [2 4] [2 5] [3 4] [3 5] [4 5] [1 2 3] [1 2 4] [1 2 5] [1 3 4] [1 3 5] [1 4 5] [2 3 4] [2 3 5] [2 4 5] [3 4 5] [1 2 3 4] [1 2 3 5] [1 2 4 5] [1 3 4 5] [2 3 4 5] [1 2 3 4 5]]
ifelse ( Display? = true ) [ display ] [ no-display ] ;; display is a switch in interface
resize-world 599 * 0 ( 599 * 1 ) ( 599 * -1 ) 599 * 0 ;; the world is 600X600 in size
setup-world
setup-patches
reset-ticks
print ( word "That setup took " timer " seconds" )
end
to setup-world
let pcolors []
set pcolors [ 25 65 23 53 105 10 ]
ask patches [
set pcolor item (random 5) pcolors
]
ask patches [
if pcolor = 25 [ set habitatcover 1 ]
if pcolor = 65 [ set habitatcover 2 ]
if pcolor = 23 [ set habitatcover 3 ]
if pcolor = 53 [ set habitatcover 4 ]
if pcolor = 105 [ set habitatcover 5 ]
if pcolor = 10 [ set habitatcover 6 ]
]
end
to setup-patches
set-patch-size 0.6 ;; view patch size
set HotPatchSet patches with [ ( habitatcover != 6 ) ]
let list1 ( list 2 4 )
let list2 ( list 5 10 )
let n0 count turtles
set CurrentHotPatchSet HotPatchSet with [ habitatcover = one-of item ValidHabsItem ValidHabs ]
while [ n0 < ( length list1 ) * ( length list2 ) * 200 ] ;; I want 200 ou more turtles in the word. Here I put 200
[
(
foreach list1
[
this-metabolism ->
foreach list2
[
this-reproduction ->
let c count CurrentHotPatchSet
if c = 0 [ stop ]
ask one-of CurrentHotPatchSet
[
sprout 1
[
set turtle-profiles-habitat item ValidHabsItem ValidHabs
set metabolism this-metabolism
set reproduction this-reproduction
setup-turtles who
]
set CurrentHotPatchSet CurrentHotPatchSet with [ not any? turtles in-radius 2 ]
]
]
]
)
set n0 count turtles
]
end
to setup-turtles [ whichTurtle? ]
set color black
ask turtle who [
(
ifelse
metabolism = 2 [set code-metabolism "M1"]
metabolism = 4 [set code-metabolism "M2"]
)
(
ifelse
reproduction = 5 [set code-reproduction "R1"]
reproduction = 10 [set code-reproduction "R2"]
)
set all-code ( word code-metabolism code-reproduction )
]
end
I'm afraid I did not look for the particular problems in your code, but there is general advice on speeding up models here:
http://jasss.soc.surrey.ac.uk/20/1/3.html
with updates here:
http://www.railsback-grimm-abm-book.com/jasss-models/
I'm pretty sure that some of the advice applies to your code.

How to extend neighbor function to 24 using code from Moore and Von Nuemman example

I am learning how to use net logo and one of the things I am trying to do is to create a larger neighborhood then the built in 8 that comes with the agent set "neighbor".
I want to use this extended neighborhood to run Conway's Game of Life with more neighbors.
I have used the built in function from the Game of Life available in the netlogo's model library.
to go
let neighbors24 [list pxcor pycor] of patches with [abs pxcor <= 2 and abs pycor <= 2]
ask patches
[ set live-neighbors count neighbors24 with [living?] ]
;; Starting a new "ask patches" here ensures that all the patches
;; finish executing the first ask before any of them start executing
;; the second ask. This keeps all the patches in synch with each other,
;; so the births and deaths at each generation all happen in lockstep.
ask patches
[ ifelse live-neighbors = 3
[ cell-birth ]
[ if live-neighbors != 2
[ cell-death ] ] ]
tick
end
I expect neighbors24 to increase the number of neighboring cells from 8 to 24, instead I am met with the following error.
"WITH expected input to be an agentset but got the list [[-2 -1] [0 0] [2 2] [-2 2] [-1 1] [2 -2] [0 2] [-1 -1] [-2 1] [-1 -2] [2 1] [1 0] [-1 0] [-1 2] [1 -1] [0 -1] [-2 0] [0 -2] [1 2] [-2 -2] [1 -2] [0 1] [2 0] [2 -1] [1 1]] instead."
NetLogo should tell you which line is giving you the error. Please include that in your future questions.
In this case, the error is (presumably) the line set live-neighbors count neighbors24 with [living?]. Your problem is that with selects those agents in the specified agentset that meet a condition. So patches with [pcolor = yellow] would get the yellow patches. However, neighbors24 is not an agentset, it's a list of patch coordinates.
It is a common NetLogo novice mistake to create lists, particularly if you have experience with other programming languages. If you are creating lists of agent identifiers (eg coordinates for patches, or who numbers for turtles) you almost certainly want an agentset instead.
The modified line let neighbors24 patches with [abs pxcor <= 2 and abs pycor <= 2] will create neighbors24 as an agentset.

agents sharing with each other their lists

I am making a NetLogo model. Each agent has a list of 5 integers (agent-list). On each tick, turtles create link with one other turtle, and share with each other their list.
turtles-own [ agent-list ]
.
.
.
ask turtles [
create-link-with one-of other turtles
set agent-list lput agent-list of link-neighbors agent-list
]
I know the code above doesn't work, how should I fix it?
The simplest way to combine the lists as you've described would probably be sentence:
turtles-own [ agent-list ]
to setup
ca
crt 3 [
set agent-list map [random 10] range 5
]
reset-ticks
end
to link-and-share
ask turtles [
let target one-of other turtles
create-link-with target
set agent-list sentence agent-list [agent-list] of target
show agent-list
]
end
However, you'll have do do some tweaking depending on what you're actually looking to do since that means that turtles linking later in the procedure are likely to pull the agent-list of turtles that have already modified their own agent-list. So, if turtle 0 grabs the agent-list of turtle 1, then later turtle 4 grabs the agent-list of turtle 0, turtle 4 would have an agent-list of 15 integers, not 10, similar to the output below:
(turtle 1): [6 1 5 4 7 3 9 8 1 1]
(turtle 0): [9 0 3 3 5 3 9 8 1 1]
(turtle 2): [3 9 8 1 1 9 0 3 3 5 3 9 8 1 1]

How to retrieve multiple variables from NetLogo agentsets in the same (not random) order?

I have a NetLogo model in which agents retrieve multiple lists of variables from other agents. The order in which these lists are returned is crucial, because variables in each list are associated with each other. However, I believe lists are returned from other agents in a random order each time. For example, take the following simplified test case:
turtles-own [testlist1 testlist2 testlist3 testlist4]
to setup
random-seed 1
clear-all
create-turtles 5
ask turtles [
create-links-with other turtles
set testlist1 []
set testlist2 []
set testlist3 []
set testlist4 []
set testlist1 lput [who] of self testlist1
set testlist2 lput [who] of self testlist2] ;identical to testlist1
end
to go
ask turtles[
set testlist3 reduce sentence [testlist1] of link-neighbors
show testlist3
set testlist4 reduce sentence [testlist2] of link-neighbors
show testlist4]
end
For my use case, values in testlist3 and testlist4 should be in the same order, but their orders differ at random. Output:
(turtle 2): [0 3 1 4]
(turtle 2): [3 4 1 0]
(turtle 3): [4 1 0 2]
(turtle 3): [1 0 2 4]
(turtle 0): [4 2 3 1]
(turtle 0): [3 4 2 1]
(turtle 1): [0 4 2 3]
(turtle 1): [4 2 3 0]
(turtle 4): [0 2 1 3]
(turtle 4): [0 3 2 1]
My question: What is the best way to return multiple lists (such as testlist and testlist2 above) from an agent-set in the same order in a given procedure?
Replacing link-neighbors with turtle-set sort link-neighbors doesn't work, because after converting the sorted list back to an agent-set, the agents in the agent-set are called in a random order. If at all possible, I'd prefer not to have to refactor the entire model from lists to matrices using the matrix extension.
You were on the right track with the idea of turning your agentset to a list. The only part missing was using map instead of turning it back into a turtle set and then using of again:
to go
ask turtles[
set testlist3 reduce sentence map [ t -> [ testlist1 ] of t ] sort link-neighbors
show testlist3
set testlist4 reduce sentence map [ t -> [ testlist2 ] of t ] sort link-neighbors
show testlist4
]
end
See this answer for a bit more detail about the parallel between list operations and agentset operations.