如何在 NetLogo 的代码中使用 foreach?

How can I use foreach inside a code in NetLogo?

我是 NetLogo 的新手,我很难理解使用 foreach 并将两个部分连接成一个代码的逻辑。谁能帮助我理解和解决我的问题?

我的问题:

我有 31 个海龟概况,涉及 5 种栖息地的组合。例如:

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

我还有 2 个变量,每个变量有 3 个级别。繁殖变量(R)和代谢变量(M),产生9种组合,即:

R1M1
R1M2
R1M3

R2M1
R2M2
R2M3

R3M1
R3M2
R3M3

我想为 31 个海龟配置文件中的每一个配置这 9 个组合。例如:

个人资料 1:

R1M1
R1M2
R1M3

R2M1
R2M2
R2M3

R3M1
R3M2
R3M3

个人资料 2:

R1M1
R1M2
R1M3

R2M1
R2M2
R2M3

R3M1
R3M2
R3M3

依此类推,直到您达到具有这 9 个级别的配置文件 31( 变量繁殖 (R) 和新陈代谢 (M) 的 3 个水平的组合)。因此,在世界上生成了 279 只海龟(31 个配置文件 * 9 = 279)

我在这方面得到了帮助link: 非常感谢

但是,我无法理解逻辑并将两段代码放在一起工作。我有这部分代码必须存在才能使以下代码结构工作:

 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 )
            ]     
    ]
  ]

我知道下面的代码行不会为每个配置文件生成 9 个相等的组合

set metabolism item 0 ( n-of 1 list1 )
set reproduction item 0 ( n-of 1 list2 )

例如,每个剖面出生了9只海龟,但有重复或不平衡。例如:

个人资料 1:

R1M3
R1M3
R1M3
R1M3
    
R2M2
    
R3M2
R3M3
R3M3
R3M1

而且我希望 31 个海龟配置文件中的每一个都具有 9 个不重复的平衡组合。例如:

个人资料 1:

R1M1
R1M2
R1M3

R2M1
R2M2
R2M3

R3M1
R3M2
R3M3

我知道使用 foreach 我可以获得 9 种所需的组合。使用以下代码:

(
 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
 ]
 ]
 ]
 )

但是尝试将这个 foreach 代码(上面)与代码的一般结构合并是行不通的。我把它放在我认为有点合乎逻辑的所有位置。它就是行不通。

有人可以向我解释一下如何将这两段代码放在一起吗?

提前致谢:)

完整代码,如下:

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

为了创建具有所有配置文件和 R 和 M 组合的海龟,同时也让补丁,海龟被放置在 one-of 海龟 profile 上,您可以重新分配补丁的habitatcover。它们之前是随机选择的,所以它不会改变随机性。

只需添加

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]
            
            ;...
          ]

我在另一个答案中给你的代码。