我们如何根据特定变量统计代理?
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
输出看起来像这样:
我们正在努力解决以下问题:
每个代理都有其特定的代码,并且在每次迭代中都会更新该迭代中存活的代理列表。我们想要计算每次迭代中有多少代理死于列表中存在的每个代码。 我们在下面有这些程序(代码)。 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
输出看起来像这样: