我想计算并存储与海龟属性相关的两个特定量,即计算有多少只海龟满足某个条件以及这些海龟特定属性的总和。该特定属性采用离散、整数、非序列值。
模型的最小示例代码如下所示:
globals [ N-x1 N-x2, N-x5 sum-A-x1 sum-A-x2 sum-A-x5 x-list ]
turtles-own [ condition1? A x ]
set x-list ( list 1 2 5 )
鉴于在实际模型中
x-list
需要 88 个离散值,我认为使用“foreach”循环将是处理此问题的适当方法。请注意,实际模型中的海龟数量约为 75k,因此效率很重要。
结合之前的答案(here和here),我想出了以下解决方案:
foreach x-list
[ x ->
; Count turtles by x
let temp1 (word "set N-x" x " count turtles with [ condition1? = true and x = " x "]" )
run temp1
; Calculate sum of A by x
let temp2 (word "set sum-A-x" x " sum [ A ] of turtles with [ condition1? = true and x = " x "]" )
; Capture errors due to empty list in calculating the sum
carefully [ run temp2 ]
[ let temp3 (word "set sum-A-x" x " 0" )
run temp3
]
]
虽然它有效,但模型的每次运行都会大大减慢。我认为有助于加快代码速度的一个简单(但粗略)的解决方案是首先定义将在其上执行后续命令(计数和求和)的海龟代理集。由于我找不到在“foreach”循环中使用
let
来执行此操作的方法,因此我采用了手动定义所有内容的手动解决方案(对于 x
的 88 个值中的每一个):
; Define needed agentsets
let turtles-x1 with [ condition1? = true and x = 1 ]
let turtles-x2 with [ condition1? = true and x = 2 ]
let turtles-x5 with [ condition1? = true and x = 5 ]
; Count turtles meeting condition1
set N-x1 count turtles-x1
set N-x2 count turtles-x2
set N-x5 count turtles-x5
; Sum A over turtles meeting condition1
if N-x1 > 0 [ set sum-A-x1 sum [ A ] of turtles-x1 ]
if N-x2 > 0 [ set sum-A-x2 sum [ A ] of turtles-x2 ]
if N-x5 > 0 [ set sum-A-x5 sum [ A ] of turtles-x5 ]
这似乎小幅提高了性能。有人能想到一种更有效(即更聪明)的方法来做同样的事情吗?例如。使用
map
(我无法理解)或 table
扩展?
编辑:虽然仍然欢迎答案,但我找到了一种使用
table
扩展和 map
来解决问题的方法。我将其留在这里,以防有人偶然发现类似的案例。
globals [ x-keys x-N turtle-list turtle-A ]
; Store table of relevant turtles and their x's (to preserve order)
let temp-table table:group-agents turtles with [ condition1? = true ] [ x ]
; Relevant turtles' Xs (in the order inserted)
set x-keys table:keys temp-table
; Counts of relevant turtles per x (in the order inserted)
set x-N map count table:values temp-table
; Relevant turtles in the order inserted (in an agentset list)
set turtle-list table:values temp-table
; Calculate sum of A per x
set turtle-A map [ y -> precision ( sum [ A ] of y ) 3 ] turtle-list
这解决了许多问题,例如预定义每个变量、执行多个
if
来检查 x 是否已填充(即 N > 0)以便运行总和以及存储不需要的信息(例如手动设置案例总和) N = 0,为零)。这极大地提高了速度并将生成的输出大小减半(在行为空间实验中)。