I'm new to NetLogo and I'm having a hard time understanding the logic of using foreach and joining two parts into a single code. Can anyone help me understand and solve my problem?
My problem:
I have 31 profiles of turtles that refer to combinations of 5 types of habitats. For example:
profile1: turtles are only born in habitat 1
profile2: turtles are only born in habitat 2
profile3: turtles are only born in habitat 3
profile4: turtles are only born in habitat 4
profile5: turtles are only born in habitat 5
profile6: turtles are only born in habitats 1 and 2
profile7: turtles are only born in habitats 1 and 3
... until you reach profile31 where the turtles are born in habitats 1, 2, 3, 4 an 5
I also have 2 variables with 3 levels each. The reproduction variable (R) and the metabolism variable (M), which results in 9 combinations, that is:
R1M1
R1M2
R1M3
R2M1
R2M2
R2M3
R3M1
R3M2
R3M3
I would like to have these 9 combinations for each of the 31 turtle profiles. For example:
Profile1:
R1M1
R1M2
R1M3
R2M1
R2M2
R2M3
R3M1
R3M2
R3M3
Profile2:
R1M1
R1M2
R1M3
R2M1
R2M2
R2M3
R3M1
R3M2
R3M3
And so on until you reach profile 31 having these 9 levels (
combinations of the 3 levels of the variables reproduction (R) and metabolism (M)). And therefore, generating 279 turtles in the world (31 profiles * 9 = 279)
I had help on this link: How to make an equitable distribution of turtles using NetLogo 6.2? and thank you very much
However, I'm not able to understand the logic and put two pieces of code to work together. I have this part of the code that has to exist for the following code structure to work:
ask AvailablePatch
[ let oneprofile 99 ;;dummy value
while [ ( count turtles-here < 1 ) and ( sum UnassignedProfileCountList > 0 ) and ( oneprofile > 0 ) ]
[
set oneprofile get-any-incomplete-profile habitatcover
if ( oneprofile > 0 )
[
sprout 1
[
set turtle-profiles-habitat oneprofile
set metabolism item 0 ( n-of 1 list1 )
set reproduction item 0 ( n-of 1 list2 )
setup-turtles who
]
set turtle-count ( turtle-count + 1 )
]
]
]
I know that the lines of code below make it not generate the 9 equal combinations for each profile
set metabolism item 0 ( n-of 1 list1 )
set reproduction item 0 ( n-of 1 list2 )
For example, 9 turtles were born for each profile, but with repetitions or unbalanced. For example:
Profile1:
R1M3
R1M3
R1M3
R1M3
R2M2
R3M2
R3M3
R3M3
R3M1
And I want for each of the 31 turtle profiles to have 9 balanced combinations without repetitions. For example:
Profile1:
R1M1
R1M2
R1M3
R2M1
R2M2
R2M3
R3M1
R3M2
R3M3
I know that using foreach I could get the 9 desired combinations. Using the code below:
(
foreach list1
[
this_metabolism ->
foreach list2
[
this_reproduction ->
ask one-of AvailablePatch
[
sprout 1
[
set metabolism this_metabolism
set reproduction this_reproduction
setup-turtles who
]
set turtle-count count turtles-here
set AvailablePatch other AvailablePatch
]
]
]
)
But trying to merge this foreach code (above) with the general structure of the code doesn't work. I've put it in all the positions I thought would be somewhat logical. And it just doesn't work.
Can someone explain to me how I could put these two pieces of code together?
Thanks in advance :)
The complete code, below:
globals [ AvailablePatch UnassignedProfileCountList ValidHabs ]
turtles-own [ metabolism reproduction code-metabolism code-reproduction all-code turtle-profiles-habitat ]
patches-own [ turtle-count habitatcover ]
to setup
clear-all
random-seed 1
read
setup-world
setup-patches
reset-ticks
foreach sort turtles
[
t ->
ask t
[
print ( word "I am turtle:" " " who " " "my profile type:" " " turtle-profiles-habitat " " "my code reproduction level:" " " code-reproduction " " "my code metabolism level:" " " code-metabolism )
]
]
end
to read
set ValidHabs [ [ 0 0 0 0 0 ] [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]]
end
to setup-world
let pcolors []
set pcolors [ 25 65 23 53 105 ]
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 ]
]
end
to-report get-any-incomplete-profile [ habtype ]
let kkk 0
let shortlist [ ]
let validhablist [];
repeat 31
[
set kkk ( kkk + 1 )
set validhablist item kkk ValidHabs
if (
(( item kkk UnassignedProfileCountList > 0 ) and ( true = member? habtype validhablist ))
)
[
set shortlist lput kkk shortlist
]
]
let mypick -1
ifelse ( 0 < length shortlist )
[
set mypick item 0 ( n-of 1 shortlist )
;; print ( word "mypick is " mypick )
let oldcount item mypick UnassignedProfileCountList
let newcount ( oldcount - 1 )
set UnassignedProfileCountList replace-item mypick UnassignedProfileCountList newcount
]
[
set mypick -1
]
report mypick
end
to setup-patches
set AvailablePatch patches with [
( pxcor mod ( 2 + 1 ) = 0 ) and ( pycor mod ( 2 + 1 ) = 0 ) ]
set UnassignedProfileCountList [ 0 ] ;; effectively start from item 1 not zero
repeat 31
[
set UnassignedProfileCountList lput 9 UnassignedProfileCountList
]
let list1 ( list 2 4 8 )
let list2 ( list 5 10 15 )
(
foreach list1
[
this_metabolism ->
foreach list2
[
this_reproduction ->
ask one-of AvailablePatch
[
sprout 1
[
set metabolism this_metabolism
set reproduction this_reproduction
setup-turtles
]
set turtle-count count turtles-here
set AvailablePatch other AvailablePatch
]
]
]
)
end
to setup-turtles
ask turtle who [
(
ifelse
metabolism = 2 [set code-metabolism "M1"]
metabolism = 4 [set code-metabolism "M2"]
metabolism = 8 [set code-metabolism "M3"]
)
(
ifelse
reproduction = 5 [set code-reproduction "R1"]
reproduction = 10 [set code-reproduction "R2"]
reproduction = 15 [set code-reproduction "R3"]
)
set all-code ( word code-metabolism code-reproduction )
]
end
In order to create turtles with all profile and R and M combinations, but also let the patches, the turtles get placed on be one-of the turtles profile, you can just reassign the patch's habitatcover. They are chosen randomly before, so it doesn't change anything about the randomness.
Just add
ask one-of AvailablePatch
[
set habitatcover one-of this-profile
if habitatcover = 1 [set pcolor 25]
if habitatcover = 2 [set pcolor 65]
if habitatcover = 3 [set pcolor 23]
if habitatcover = 4 [set pcolor 53]
if habitatcover = 5 [set pcolor 105]
;...
]
to the code I gave you in the other answer.
Related
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
I have no idea how to solve the following problem:
I have 9 turtle profiles which are:
profile1: M1R1
profile2: M1R2
profile3: M1R3
profile4: M2R1
profile5: M2R2
profile6: M2R3
profile7: M3R1
profile8: M3R2
profile9: M3R3
M= metabolism and R = reproduction.
I would like the world to have an exact number of turtles born in each of these profiles. For example:
profile1: 2 turtles
profile2: 2 turtles
profile3: 2 turtles
profile4: 2 turtles
profile5: 2 turtles
profile6: 2 turtles
profile7: 2 turtles
profile8: 2 turtles
profile9: 2 turtles
It turns out that I'm just getting to have variable numbers between the profiles. is it possible for me to distribute exact amount of turtle breeding for each profile? If yes, could anyone suggest some sort of solution? Well, I've been trying to solve this for a long time!!! :)
Thanks in advance
globals [ AvailablePatch ]
turtles-own [ metabolism reproduction code-metabolism code-reproduction all-code ]
patches-own [ turtle-count ]
to setup
clear-all
let list1 ( list 2 4 8 )
let list2 ( list 5 10 15 )
let n 2 ;; 20 meters away each turtle will be from another turtle
set AvailablePatch patches with [ ( pxcor mod ( n + 1 ) = 0 ) and ( pycor mod ( n + 1 ) = 0 ) ]
ask AvailablePatch
[
sprout 1
[
set metabolism item 0 ( n-of 1 list1 )
set reproduction item 0 ( n-of 1 list2 )
setup-turtles who
]
set turtle-count ( turtle-count + 1 )
]
end
to setup-turtles [ whichTurtle? ]
ask turtle who [
(
ifelse
metabolism = 2 [
set code-metabolism "M1"
(
ifelse
reproduction = 5 [
set code-reproduction "R1"
]
reproduction = 10 [
set code-reproduction "R2"
]
reproduction = 15 [
set code-reproduction "R3"
]
)
]
metabolism = 4 [
set code-metabolism "M2"
(
ifelse
reproduction = 5 [
set code-reproduction "R1"
]
reproduction = 10 [
set code-reproduction "R2"
]
reproduction = 15 [
set code-reproduction "R3"
]
)
]
metabolism = 8 [
set code-metabolism "M3"
(
ifelse
reproduction = 5 [
set code-reproduction "R1"
]
reproduction = 10 [
set code-reproduction "R2"
]
reproduction = 15 [
set code-reproduction "R3"
]
)
]
)
set all-code ( word code-metabolism code-reproduction )
]
end
What you could do, is to:
use 2 foreach loops. That way, you get all combinations of listitems:
let list1 ( list 2 4 8 )
let list2 ( list 5 10 15 )
foreach list1
[
this_metabolism ->
foreach list2
[
this_reproduction ->
show word this_metabolism this_reproduction
;... other procedures
]
]
Now you want to create a turtle (or more) for each of this combinations, but only on a AvailablePatch:
ask one-of AvailablePatch
[
sprout 1
[
set metabolism this_metabolism
set reproduction this_reproduction
setup-turtle
]
set turtle-count turtles-here
set AvailablePatch other AvailablePatch ;this patch is no longer available
]
If you want more than one turtle per combination, instead of ask one-of AvailablePatch use for example ask n-of 3 AvailablePatch.
I changed some more things on your code:
there is a reporter, that reports an agentset containing all the turtles on the patch set turtle-count count turtles-here. You don't even have to update it there, but just call count turtles-here instead of turtle-count, when you need it. That way you don't have to add and substract turtles everytime you create new ones or some die.
inside sprout its already "turtle code". Meaning that you don't have to call the procedure with a turtle's who number, but you can write the code as it was inside an ask turtle [...] block.
the ifelse cases inside setup-turtles are independed, so it can be simplified.
Full code:
globals [ AvailablePatch ]
turtles-own [ metabolism reproduction code-metabolism code-reproduction all-code ]
patches-own [ turtle-count ]
to setup
clear-all
let list1 ( list 2 4 8 )
let list2 ( list 5 10 15 )
let n 2 ;; 20 meters away each turtle will be from another turtle
set AvailablePatch patches with [ ( pxcor mod ( n + 1 ) = 0 ) and ( pycor mod ( n + 1 ) = 0 ) ]
(
foreach list1
[
this_metabolism ->
foreach list2
[
this_reproduction ->
ask one-of AvailablePatch
[
sprout 1
[
set metabolism this_metabolism
set reproduction this_reproduction
setup-turtle
]
set turtle-count count turtles-here
set AvailablePatch other AvailablePatch
]
]
]
)
end
to setup-turtle ;turtle procedure
(
ifelse
metabolism = 2 [set code-metabolism "M1"]
metabolism = 4 [set code-metabolism "M2"]
metabolism = 8 [set code-metabolism "M3"]
)
(
ifelse
reproduction = 5 [set code-reproduction "R1"]
reproduction = 10 [set code-reproduction "R2"]
reproduction = 15 [set code-reproduction "R3"]
)
set all-code ( word code-metabolism code-reproduction )
set color reproduction
set pcolor metabolism
end
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.
I have a problem that I asked for help here: How to make an equal distribution of turtles for each profile type using NetLogo 6.2?
And Lena helped me a lot :)
But, I was not very precise in what I would like and it was partially solved. I tried to adjust how Lena responded and I couldn't, because I get stuck in the very similar problem that I still don't understand how to deal in the code.
So my problem is the following:
I have 31 profiles of turtles that refer to combinations of 5 types of habitats. For example:
profile1: turtles are only born in habitat 1
profile2: turtles are only born in habitat 2
profile3: turtles are only born in habitat 3
profile4: turtles are only born in habitat 4
profile5: turtles are only born in habitat 5
profile6: turtles are only born in habitats 1 and 2
profile6: turtles are only born in habitats 1 and 3
... until you reach profile 31 where the turtles are born in habitats 1, 2, 3, 4 and 5
The problem is that I have 2 more variables (metabolism (M) and reproduction (R)), each with 3 levels:
M1R1
M1R2
M1R3
M2R1
M2R2
M2R3
M3R1
M3R2
M3R3
I would like to have exactly these nine combinations for the 31 turtle profiles. For example:
Perfil1 (turtles are only born in habitat 1):
M1R1
M1R2
M1R3
M2R1
M2R2
M2R3
M3R1
M3R2
M3R3
Perfil2 (turtles are only born in habitat 2):
M1R1
M1R2
M1R3
M2R1
M2R2
M2R3
M3R1
M3R2
M3R3
... until you reach profile 31 where the turtles are born in habitats 1, 2, 3, 4 and 5:
M1R1
M1R2
M1R3
M2R1
M2R2
M2R3
M3R1
M3R2
M3R3
The issue is that I get the following return:
profile21: M1R1
profile17: M1R2
profile20: M1R3
profile17: M2R1
profile6: M2R2
profile26: M2R3
profile30: M3R1
profile7: M3R2
profile27: M3R3
But what I would like is to have this combination of metabolism and reproduction variables for each of the 31 profiles. Like for example:
profile1: M1R1
profile1: M1R2
profile1: M1R3
profile1: M2R1
profile1: M2R2
profile1: M2R3
profile1: M3R1
profile1: M3R2
profile1: M3R3
profile2: M1R1
profile2: M1R2
profile2: M1R3
profile2: M2R1
profile2: M2R2
profile2: M2R3
profile2: M3R1
profile2: M3R2
profile2: M3R3
... until you reach profile 31
profile31: M1R1
profile31: M1R2
profile31: M1R3
profile31: M2R1
profile31: M2R2
profile31: M2R3
profile31: M3R1
profile31: M3R2
profile31: M3R3
Could anyone help me understand how I can solve this?
Thanks in advance :)
The code, below:
globals [ AvailablePatch UnassignedProfileCountList ValidHabs ]
turtles-own [ metabolism reproduction code-metabolism code-reproduction all-code turtle-profiles-habitat ]
patches-own [ turtle-count habitatcover ]
to setup
clear-all
random-seed 1
resize-world 69 * 0 ( 69 * 1 ) ( 69 * -1 ) 69 * 0
read
setup-patches
reset-ticks
foreach sort turtles
[
t ->
ask t
[
print ( word "I am turtle:" " " who " " "my profile type:" " " turtle-profiles-habitat " " "my code:" " " all-code " " "my code reproduction level:" " " code-reproduction " " "my code metabolism level:" " " code-metabolism )
]
]
end
to read
set ValidHabs [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ]
end
to-report get-any-incomplete-profile [ habtype ]
let kkk 0
let shortlist [ ]
let validhablist [];
repeat 30
[
set kkk ( kkk + 1 )
set validhablist item kkk ValidHabs
if (
(( item kkk UnassignedProfileCountList > 0 ) and ( true = member? habtype validhablist ))
)
[
set shortlist lput kkk shortlist
]
]
let mypick -1
ifelse ( 0 < length shortlist )
[
set mypick item 0 ( n-of 1 shortlist )
let oldcount item mypick UnassignedProfileCountList
let newcount ( oldcount - 1 )
set UnassignedProfileCountList replace-item mypick UnassignedProfileCountList newcount
]
[
set mypick -1
]
report mypick
end
to setup-patches
let n 2
set AvailablePatch patches with [
( pxcor mod ( n + 1 ) = 0 ) and ( pycor mod ( n + 1 ) = 0 ) ]
set UnassignedProfileCountList [ 0 ]
repeat 30
[
set UnassignedProfileCountList lput 9 UnassignedProfileCountList
]
let list1 ( list 2 4 8 )
let list2 ( list 5 10 15 )
(
foreach list1
[
this-metabolism ->
foreach list2
[
this-reproduction ->
ask one-of AvailablePatch
[
sprout 1
[
set turtle-profiles-habitat oneprofile
set metabolism this-metabolism
set reproduction this-reproduction
setup-turtles
]
set turtle-count count turtles-here
set AvailablePatch other AvailablePatch
]
]
]
]
]
)
end
to setup-turtles
(
ifelse
metabolism = 2 [set code-metabolism "M1"]
metabolism = 4 [set code-metabolism "M2"]
metabolism = 8 [set code-metabolism "M3"]
)
(
ifelse
reproduction = 5 [set code-reproduction "R1"]
reproduction = 10 [set code-reproduction "R2"]
reproduction = 15 [set code-reproduction "R3"]
)
set all-code ( word code-metabolism code-reproduction )
set color reproduction
set pcolor metabolism
end
Again, you have a list and want to create a specific number of turtles for each combination of this list with the other lists. So, you can use a foreach loop:
foreach ValidHabs [
this-profile ->
;code that should be run for every entry of ValidHabs
]
The whole setup-patches function:
to setup-patches
let n 2 ;; 20 meters away each turtle will be from another turtle
set AvailablePatch patches with [
( pxcor mod ( n + 1 ) = 0 ) and ( pycor mod ( n + 1 ) = 0 ) ]
set UnassignedProfileCountList [ 0 ] ;; effectively start from item 1 not zero
repeat 30
[
set UnassignedProfileCountList lput 9 UnassignedProfileCountList
]
let list1 ( list 2 4 8 )
let list2 ( list 5 10 15 )
(
foreach ValidHabs [
this-profile ->
foreach list1
[
this-metabolism ->
foreach list2
[
this-reproduction ->
ask one-of AvailablePatch
[
sprout 1
[
set turtle-profiles-habitat this-profile
set metabolism this-metabolism
set reproduction this-reproduction
setup-turtles
]
set turtle-count count turtles-here
set AvailablePatch other AvailablePatch ;this patch is no longer available
]
]
]
]
)
end
I will be very grateful if someone could give me any kind of advice about a problem that I have in my code. I am working on a model with four kind of agents. Each type of agents uses a different strategy. These strategies are Prisoner Dilemma variations. Two of these strategies (tit for tat and unforgiving) need to record (in a list) who was the partner of interaction, and depending if that partner defected or not, will be the behave (cooperative or defect) of the agent in the next encounter with the same partner. Agents move randomly through the world. The problem come when agents die or birth according of their resources level. At this point these strategies that require to record who was the previous partner and how was his behave (cooperative or defect) do not work. This is the message that show up.
I am really appreciate any support!!!!.
number of initial turtles is 42, but two ticks later the number is 52
Below is a code that reproduces the error. In order to run it, it is necessary to create the sliders: n-tit-for-tat-com; n-unforgiving-com; inc-ecological-resources; energy-consume-companies:
globals
[
;;Number of companies with each strategy¨
num-tit-for-tat-com
num-unforgiving-com
;;number of interactions by each strategy
num-tit-for-tat-com-games
num-unforgiving-com-games
;; Total score of all companies playing each strategy
tit-for-tat-com-score
unforgiving-com-score
; Total companies en each ticks
num-companies
]
breed [companies company]
;;create companies variables
companies-own [
score-com
score-com-round
strategy-com
defect-now?-com
partner-defected?-com ;;action of the partner
partnered?-com ;;am I partnered?
partner-com ;;WHO of my partner (nobody if not partnered)
partner-history-com ;;a list containing information about past interactions with other turtles (indexed by WHO values)
earnings-tit-for-tat-Com
earnings-unforgiving-Com
earnings-com
tit-for-tat-com-score-round
unforgiving-com-score-round
]
patches-own
[
resources-amount ;; resources amount in each patches
resources-to ;; aux variable to count resources taken
]
;;;Setup Procedures;;;
to setup
clear-all
setup-patches
setup-companies ;;setup the turtles and distribute them randomly
reset-ticks
end
; Setup patches
;===============
to setup-patches
ask patches [set resources-amount random 4] ;; patches represent ecological system. Resources are distributed randomly. [0,1,2 or 3] 0 -> non resources; 3 -> plenty of resources
ask patches [
set pcolor (ifelse-value
resources-amount = 0 [49]
resources-amount = 1 [58]
resources-amount = 2 [67]
resources-amount = 3 [65]
[63] ;; this case never happen. Because 4 means integer number in range [0 to 3]
)]
end
to setup-companies
make-companies ;;create the appropriate number of turtles playing each strategy
setup-common-variables-com ;;sets the variables that all turtles share
end
;;create the appropriate number of turtles playing each strategy
to make-companies
create-companies n-tit-for-tat-com
[ set strategy-com "tit-for-tat-com"
set color 135
set earnings-tit-for-tat-Com random 4 + 1 ;;randomly initial resources in the range [ 1 - 4 ]. It is sum + 1 to enforce never inicial resource = 0
]
create-companies n-unforgiving-com
[ set strategy-com "unforgiving-com"
set color 4
set earnings-unforgiving-Com random 4 + 1 ;;randomly initial resources in the range [ 1 - 4 ]. It is sum + 1 to enforce never inicial resource = 0
]
end
; Setup common variables
;¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
;;set the variables that all turtles share
to setup-common-variables-com
ask companies [
set shape "pentagon"
set size 1.3
set tit-for-tat-com-score-round 0
set unforgiving-com-score-round 0
set score-com 0
set partnered?-com false
set partner-com nobody
setxy random-xcor random-ycor
]
end
;;;Runtime Procedures;;;
to go
ask companies [birth-die-com]
store-initial-companies-counts ;;record the number of turtles for each strategy
setup-history-lists-com
clear-last-round
ask companies [ partner-up-com ] ;;have turtles try to find a partner
let partnered-com companies with [ partnered?-com ]
ask partnered-com [ select-strategy-com ] ;;all partnered turtles select action
ask partnered-com [ play-a-round-com ]
adjust-patches
tick
end
;Birth-die-com ; According to the level of resources companies can die or birth
;======================
to birth-die-com
(ifelse
strategy-com = "tit-for-tat-com"
[
set earnings-com earnings-tit-for-tat-com
(if earnings-com > 2 * energy-consume-companies [
hatch 1 [set earnings-tit-for-tat-com random 2 + 1 ] ;;randomly initial resources in the range [ 1 - 2 ]. It is sum + 1 to enforce never inicial resource = 0
set earnings-com (earnings-com - energy-consume-companies )])
( if earnings-com < energy-consume-companies [ die ])
]
strategy-com = "unforgiving-com"
[
set earnings-com earnings-unforgiving-com
(if earnings-com > 2 * energy-consume-companies [
hatch 1 [set earnings-unforgiving-com random 2 + 1 ] ;;randomly initial resources in the range [ 1 - 2 ]. It is sum + 1 to enforce never inicial resource = 0
set earnings-com (earnings-com - energy-consume-companies )])
( if earnings-com < energy-consume-companies [ die ])
]
)
end
;;STORE INITIAL COMPANIES¨
;===========================
;;record the number of turtles at the begining of each tick
;;The number of turtles of each strategy is used when calculating average payoffs.
to store-initial-companies-counts
set num-tit-for-tat-com (count companies with [strategy-com = "tit-for-tat-com"])
set num-unforgiving-com (count companies with [strategy-com = "unforgiving-com"])
end
;Setup-History-Lists-com;; initialize PARTNER-HISTORY list in all turtles
;========================
to setup-history-lists-com
set num-companies (count companies)
let default-history-com [] ;;initialize the DEFAULT-HISTORY variable to be a list
;create a list with NUM-TURTLE elements for storing partner histories
repeat (count companies) [ set default-history-com (fput false default-history-com) ]
;give each turtle a copy of this list for tracking partner histories
ask companies [ set partner-history-com default-history-com ]
end
;Clear-last-round
;================
to clear-last-round
let partnered-com companies with [ partnered?-com ]
ask partnered-com [ release-partners-com ]
end
; release partner between companies and turn around
;¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
to release-partners-com
set partnered?-com false
set partner-com nobody
rt 180
set label ""
end
;;have turtles try to find a partner
;;Since other turtles that have already executed partner-up may have
;;caused the turtle executing partner-up to be partnered,
;;a check is needed to make sure the calling turtle isn't partnered.
;;partner-up. Find partner
;===========================
to partner-up-com ;;turtle procedure
if (not partnered?-com) [ ;;make sure still not partnered
rt (random-float 90 - random-float 90) fd 1 ;;move around randomly
set partner-com one-of other (companies in-radius 1 ) with [ not partnered?-com ]
if partner-com != nobody [ ;;if successful grabbing a partner, partner up
set partnered?-com true
set heading 270 ;;face partner
ask partner-com [
set partnered?-com true
set partner-com myself
set heading 90
]
]
]
end
;Select stratey company
;¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
;;choose an action based upon the strategy being played
to select-strategy-com ;;turtle procedure
if strategy-com = "tit-for-tat-com" [ tit-for-tat-com ]
if strategy-com = "unforgiving-com" [ unforgiving-com ]
end
;Play a round-companies
;¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
to play-a-round-com ;;turtle procedure
get-payoff-com ;;calculate the payoff for this round
update-history-com ;;store the results for next time
end
; get-payoff-com
;¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
;;calculate the payoff for this round and
;;display a label with that payoff.
;; Strategy-companies
;Turtles l l
;Action l C l D
;__________l________ l__________
; C l 3 l -3
;----------l---------l----------
; D l 5 l -2
to get-payoff-com
set partner-defected?-com [defect-now?-com] of partner-com
ifelse partner-defected?-com [
ifelse defect-now?-com
[ set score-com (score-com + 1 ) set label 1 set score-com-round 1 ]
[set score-com (score-com + 0) set label 0 set score-com-round 0]
]
[ifelse defect-now?-com
[set score-com (score-com + 5) set label 5 set score-com-round 5]
[set score-com (score-com + 3) set label 3 set score-com-round 3]
]
end
;Update-history
;¨¨¨¨¨¨¨¨¨¨¨¨¨¨
;;update PARTNER-HISTORY based upon the strategy being played
to update-history-com
if strategy-com = "tit-for-tat-com" [ tit-for-tat-com-history-update ]
if strategy-com = "unforgiving-com" [ unforgiving-com-history-update ]
end
;;;Strategies;;;
; Tit-for-tat-com
;¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
to tit-for-tat-com
set num-tit-for-tat-com-games num-tit-for-tat-com-games + 1
set partner-defected?-com item ([who] of partner-com) partner-history-com
ifelse (partner-defected?-com)
[set defect-now?-com true]
[set defect-now?-com false]
ask companies in-radius 1 [
ask patches in-radius 1 [set resources-to (resources-amount * 1)]
ask patches in-radius 1 [set resources-amount (resources-amount - resources-to)]
set tit-for-tat-com-score-round ( tit-for-tat-com-score-round + score-com-round )
set earnings-tit-for-tat-com (earnings-tit-for-tat-Com + ((sum [ resources-to ] of patches in-radius 1)/ 2) + tit-for-tat-com-score-round - energy-consume-companies )
ask patches in-radius 1 [set resources-to 0 ]
set tit-for-tat-com-score-round 0
]
end
;Tit-for-tat-com-history-update¨
;¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
to tit-for-tat-com-history-update
set partner-history-com
(replace-item ([who] of partner-com) partner-history-com partner-defected?-com)
end
;unforgiving-com ; Works similar to tit-for-tat, but once the another defect, always defect
;¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
to unforgiving-com
set num-unforgiving-com-games num-unforgiving-com-games + 1
set partner-defected?-com item ([who] of partner-com) partner-history-com
ifelse (partner-defected?-com)
[set defect-now?-com true]
[set defect-now?-com false]
ask companies in-radius 1 [
ask patches in-radius 1 [set resources-to (resources-amount * 1)]
ask patches in-radius 1 [set resources-amount (resources-amount - resources-to)]
set unforgiving-com-score-round ( unforgiving-com-score-round + score-com-round )
set earnings-unforgiving-com (earnings-unforgiving-Com + ((sum [ resources-to ] of patches in-radius 1)/ 2) + unforgiving-com-score-round - energy-consume-companies)
ask patches in-radius 1 [set resources-to 0 ]
set unforgiving-com-score-round 0
]
end
;unforgiving-com-history-update
;¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
to unforgiving-com-history-update
if partner-defected?-com [
set partner-history-com
(replace-item ([who] of partner-com) partner-history-com partner-defected?-com)
]
end
;; Adjusting Patches
;; Put limits
to adjust-patches
ask patches [ set resources-amount resources-amount + random-float Inc-Ecological-resources ] ;; Resources are renewable. They grow up again between [0-3). Use Slider
ask patches [ ;; Resources range [0-3)
set resources-amount (ifelse-value
resources-amount < 0 [0] ;;
resources-amount > 3 [3] ;;
[resources-amount]
)
]
;; Patches are colored according their level
ask patches [
set pcolor (ifelse-value
resources-amount < 0 [ black ]
resources-amount = 0 [ 38 ]
resources-amount > 0 and resources-amount <= 0.5 [ 49 ]
resources-amount > 0.5 and resources-amount <= 2 [ 67 ]
resources-amount > 2 and resources-amount <= 3 [ 65 ]
resources-amount > 3 and resources-amount <= 4 [ 63 ]
[ white ])
]
end