NetLogo中的嵌套foreach
我试图计算一组数字的基尼系数。基尼系数是平均绝对差值的一半。也就是说,对于列表中的每一对可能的数字,我需要取它们的绝对差,并将这些差加在一起(以及其他一些东西)。这是我的密码NetLogo中的嵌套foreach,netlogo,Netlogo,我试图计算一组数字的基尼系数。基尼系数是平均绝对差值的一半。也就是说,对于列表中的每一对可能的数字,我需要取它们的绝对差,并将这些差加在一起(以及其他一些东西)。这是我的密码 to-report calc-Gini [list-Values] let sumdiff 0 foreach list-Values [ foreach list-Values [ set sumdiff sumdiff + abs ( ?1 - ?2 ) ] ] report 0.5
to-report calc-Gini [list-Values]
let sumdiff 0
foreach list-Values
[ foreach list-Values
[ set sumdiff sumdiff + abs ( ?1 - ?2 )
]
]
report 0.5 * sumdiff / (mean list-Values * (length list-Values) ^ 2)
end
当我测试它时(例如show calc Gini(列表1 2 3)
),我在第二个foreach
上得到一个错误“任务预期2个输入,但只得到1”
我认为问题在于NetLogo希望同时运行foreach循环。因此,如果列表长度为N,那么它只创建N对(即,列表1中的第一项和列表2中的第一项,然后是每个列表中的第二项等),这就是等长列表的要求的来源。但是我需要它来处理通过交叉列表获得的N^2对
如何使嵌套的
foreach
执行我想要的操作和/或其他原语更合适?我无法解决嵌套的foreach
方法,但这可能是执行计算的另一种方法:
如果使用有序数据,则可以使用此方程式计算基尼系数(给定向量$y$和$y_i$,$i=1,…,n$)
$$G(y)=\frac{1}{n}(n+1-2*\frac{\sum{i=1}{n}(n+1-i)y{i}{\sum{i=1}{y}$$
以下记者应在NetLogo中发布结果:
to-report calc-Gini [list-Values]
let values sort list-Values ; making sure values are in a non-decreasing order
let n length values
let i 1
let numerator []
foreach values
[ set numerator lput ( (n + 1 - i) * ? ) numerator
set i i + 1
]
report 1 / n * ( n + 1 - 2 * (sum(numerator) / sum(values)) )
end
NetLogo没有将
-1
和-2
绑定到外部任务和内部任务的机制。当它在代码中看到-1
和-2
时,它希望两个输入都来自内部任务。由于内部foreach
只提供一个输入,NetLogo会抱怨
您只需将外部foreach
的输入分配给一个局部变量即可解决该问题:
to-report calc-Gini [list-Values]
let sumdiff 0
foreach list-Values
[ let v ?
foreach list-Values
[ set sumdiff sumdiff + abs ( v - ? )
]
]
report 0.5 * sumdiff / (mean list-Values * (length list-Values) ^ 2)
end
也就是说,这里有一个替代实现:
to-report calc-gini [ xs ]
report 0.5 * sum map [ sum-diff ? xs ] xs / (mean xs * (length xs) ^ 2)
end
to-report sum-diff [ x xs ]
report sum map [ abs (x - ?) ] xs
end
谢谢Nicolas-完美。代码运行后,我意识到等式中缺少了一个术语,因此编辑了我的问题和你的答案,以防有人通过搜索基尼系数发现