在NetLogo中嵌套的foreach

时间:2015-08-03 09:20:10

标签: 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 * sumdiff / (mean list-Values * (length list-Values) ^ 2)
end

当我测试它时(例如show calc-Gini (list 1 2 3))我在第二个foreach上收到错误“任务预期2个输入,但只有1个”。

我认为问题是NetLogo想要同时运行foreach循环。因此,如果列表长度为N,则它仅创建N对(即list1中的第一项和list2中的第一项,然后是每个列表中的第二项等),这是对等长列表的要求来自的地方。但是我需要它来处理通过越过列表获得的N ^ 2对。

如何让嵌套的foreach做我想要的和/或更合适的其他原语?

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

我无法解决您的嵌套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} ^ {n} y_i} $$

以下记者应该在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