我们如何根据特定变量统计代理?

How can we count agents according to specific variables?

我们正在努力解决以下问题:

每个代理都有其特定的代码,并且在每次迭代中都会更新该迭代中存活的代理列表。我们想要计算每次迭代中有多少代理死于列表中存在的每个代码。 我们在下面有这些程序(代码)。 Obs:由于 turtle profile

导出的输出,我们需要使用 profile 列表

对于下面的大代码,我们深表歉意,但我们已尽力将其减少为可重现的代码

提前致谢

globals [ ListProfiles Death ]

turtles-own [ profiles-code metabolism-code reproduction-code metabolism reproduction resource-turtle ]

patches-own [ resources ]

to setup
  ca
  prepare
  ask patches [ set resources random 100 ]
  let list1 ( list 2 4 )
  let list2 ( list 5 10 )
  (
    foreach list1
  [
    this-metabolism ->

      foreach list2
      [
        this-reproduction ->
        ask n-of 1 patches
        [
          sprout 1
          [
            set metabolism this-metabolism
            set reproduction this-reproduction
            setup-turtles
          ]
        ]
      ]
    ]
  )
  reset-ticks
end

to setup-turtles
  (
    ifelse
    metabolism = 2 [ set metabolism-code "M1" ]
    metabolism = 4 [ set metabolism-code "M2" ]
  )

  (
    ifelse
    reproduction = 5 [ set reproduction-code "R1" ]
    reproduction = 10 [ set reproduction-code "R2" ]
  )
  set profiles-code ( word metabolism-code reproduction-code )
  print ( word "profiles-code: " profiles-code )
end

to go
  ListProfilesProc
  MetaboProc
  ProbDieProc
  output

  tick
end

to ListProfilesProc
  set ListProfiles [ ]
  ask turtles [
    set ListProfiles lput profiles-code ListProfiles
  ]
  set ListProfiles remove-duplicates ListProfiles
end

to MetaboProc
  ask turtles [
    (
      ifelse
    metabolism = 2
      [
        set resource-turtle ( resources - metabolism )
        if resource-turtle <= 60 [ DieProc ]
        (
          ifelse
          reproduction = 5
          [
            if resource-turtle >= 5 [ hatch 1 ]
          ]
          reproduction = 10
          [
            if resource-turtle >= 10 [ hatch 1 ]
          ]
        )
      ]
    )
  ]
end

to DieProc
  let code profiles-code
  foreach ListProfiles [ lp ->    ;; I think, here's the problem... I can't individualize the kills by code. I've already tried several things. And therefore I can't get the output of the deaths by code. It is always repeated (general calculation)...
    
    if lp = code
    [
      set Death Death + 1
    ]
  ]
  die
end

to ProbDieProc
  ask turtles
  [
    let prob-die random-float 1.01
    if prob-die < 0.77 [ DieProc ]
  ]
end

to prepare
  carefully
    [ file-delete ( word "output.csv" ) ]
  [ ]
  file-open  ( word "output.csv" )
  file-print ( word "code_profile,death,tick" )
  file-close
end

to output
  file-open ( "output.csv" )
  foreach ListProfiles
  [
    t ->
    file-print ( word t "," Death "," ticks )
  ]
  file-close
end

Deaths 因为它是一个 global 变量,这意味着任何时候 any turtle 访问它(更新或读取),他们都在“分享”相同的价值。相反,您需要跟踪 each 配置文件类型的死亡。你拥有它的方式,其中 profiles-code 区分不同的海龟类型,你可以通过几种方式解决这个问题 - 例如:你可以为每种配置文件类型创建特定的 Death 跟踪器(例如 Death-M1R1, Death-M1R2...等)并根据需要输出;或者您可以使用一个列表,您可以在其中更新列表中与特定配置文件相对应的项目;或者您可以使用列表列表并使用 position 获取不同 breed 的死亡值;或者您可以使用 tables 扩展名,这是我将在下面展示的示例,因为我认为它是最干净和最明确的。

如果您在其他编码语言中使用过 tables 扩展,则它允许类似于字典结构的内容,其中您有一个 {KEY: VALUE} 对,这样如果您输入 KEY,您将获得出价值。所以这里的一般工作流程是建立一个字典来存储每个配置文件类型的名称和死亡计数。然后,每当海龟死亡时,它都会更新字典中其配置文件类型的死亡计数。

为简单起见,我只对上面的代码做了一些小改动,并在我进行(最多)更新的地方添加了注释:

extensions [ table ]

globals [ ListProfiles Death NInitial NFinal R Birth deaths-dict ]

turtles-own [ profiles-code metabolism-code reproduction-code metabolism reproduction resource-turtle ]

patches-own [ resources ]

to setup
  ca
  prepare
  ; Define deaths-list as a list
  set deaths-dict table:make
  ask patches [ set resources random 100 ]
  let list1 ( list 2 4 )
  let list2 ( list 5 10 )
  (
    foreach list1
  [
    this-metabolism ->

      foreach list2
      [
        this-reproduction ->
        ask n-of 1 patches
        [
          sprout 1
          [
            set metabolism this-metabolism
            set reproduction this-reproduction
            setup-turtles
            ; Add each metabolism / reproduction to the deaths dictionary with 0 as initial deaths value
            table:put deaths-dict ( word metabolism-code reproduction-code ) 0
          ]
        ]
      ]
    ]
  )
  print deaths-dict
  reset-ticks
end

to setup-turtles
  (
    ifelse
    metabolism = 2 [ set metabolism-code "M1" ]
    metabolism = 4 [ set metabolism-code "M2" ]
  )

  (
    ifelse
    reproduction = 5 [ set reproduction-code "R1" ]
    reproduction = 10 [ set reproduction-code "R2" ]
  )
  set profiles-code ( word metabolism-code reproduction-code )
  print ( word "profiles-code: " profiles-code )
end

to go
  ; Stop the model if no turtles exist
  if not any? turtles [ stop ]
  ListProfilesProc
  MetaboProc
  ProbDieProc
  output
  tick   
end

to ListProfilesProc
  ; Simple way to get a sorted list of profile types
  set ListProfiles sort remove-duplicates [ profiles-code ] of turtles
end

to MetaboProc
  ask turtles [
    (
      ifelse
    metabolism = 2
      [
        set resource-turtle ( resources - metabolism )
        if resource-turtle <= 60 [ DieProc ]
        (
          ifelse
          reproduction = 5
          [
            if resource-turtle >= 5 [ hatch 1 ]
          ]
          reproduction = 10
          [
            if resource-turtle >= 10 [ hatch 1 ]
          ]
        )
      ]
    )
  ]
end

to ProbDieProc
  print "Running die proc..."

  ask turtles
  [
    let prob-die random-float 1
    if prob-die < 0.4 [
      DieProc
    ]
  ]
end

to DieProc
  ; Pull current death count for this profile
  let current-profile-death-count table:get deaths-dict profiles-code
  ; Increase that death count by one
  let current-profile-new-death-count current-profile-death-count + 1
  ; Update the death count in the master dictionary
  table:put deaths-dict profiles-code current-profile-new-death-count
  die
end

to prepare
  carefully
    [ file-delete ( word "output.csv" ) ]
  [ ]
  print "opening..."
  file-open  ( word "output.csv" )
  file-print ( word "code_profile,death,tick" )
  file-close
end

to output
  file-open ( "output.csv" )
  foreach ListProfiles
  [
    t ->
    let profile-deaths table:get deaths-dict t
    file-print ( word t "," profile-deaths "," ticks )
  ]
  file-close
end

输出看起来像这样: