2015-08-03 2 views
1

Я пытаюсь вычислить коэффициент Джини набора чисел. Коэффициент Джини составляет половину средней абсолютной разности. То есть, для каждой возможной пары чисел в списке, я должен принять их абсолютную разницу и добавить эти различия вместе (и некоторые другие вещи). Это мой кодВложенный foreach в 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)) Я получаю сообщение об ошибке «задачи ожидается 2 входа, но только получил 1» на втором foreach.

Я думаю, проблема в том, что NetLogo хочет одновременно проходить через петли foreach. Поэтому, если длина списка равна N, тогда он создает только N пар (то есть первый элемент в списке1 и первый элемент в списке2, затем второй элемент в каждом списке и т. Д.), В котором возникает требование для списков с равной длиной. Но мне нужно, чтобы он работал с парами N^2, полученными перекрестком списков.

Как я могу сделать вложенный foreach делать то, что я хочу, и/или какой-то другой примитив более уместен?

ответ

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

благодаря Nicolas - идеально. Как только код работал, я понял, что у меня отсутствует термин в уравнении, поэтому отредактировал мой вопрос и ваш ответ, если кто-то найдет это от поиска коэффициента Джини – JenB

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 
Смежные вопросы