NetLogo,从列表中加权随机抽取:如何使用rnd-extension?

时间:2014-03-24 16:46:26

标签: netlogo

我在NetLogo中有一个列表,其中包含值和每个值的概率列表。现在我想基于其概率(加权随机抽取)绘制随机值。我想过使用Rnd extension,但是我无法弄清楚如何确保权重,请帮助

set values [1 2 3]
set probabilities [0.2 0.3 0.5]

set state ( rnd:weighted-one-of agentset reporter-task )

2 个答案:

答案 0 :(得分:3)

如果您希望/需要为您的值和概率使用两个单独的列表,那么执行此操作的方法是让扩展选择索引并使用此索引来访问两者中的概率记者转到rnd:weighted-one-of,一旦选中,就会列出您的清单中的值。这是下面代码中的example1

但是,如果您可以将值和概率放在同一列表中,则扩展更容易使用。这是通过构建“对”列表(即,每个子列表中具有两个项目的列表的列表)来完成的。如果有,您可以使用记者中的第二项(item 1)并使用该对中的第一项(item 0)设置您的状态。 example2显示了如何执行此操作。

extensions [ rnd ]

to example1
  let values [1 2 3]
  let probabilities [0.2 0.3 0.5]
  let indices n-values length values [ ? ]
  let index rnd:weighted-one-of indices [ item ? probabilities ]
  let state item index values
end

to example2
  let pairs [[1 0.2] [2 0.3] [3 0.5]]
  let state item 0 rnd:weighted-one-of pairs [ item 1 ? ]
end

修改

正如Seth在评论中所提到的,您可以使用(map list values probabilities)从两个单独的列表中构建对的列表。他还提到,使用firstlast代替item 0item 1,代码可能更“清晰”。

example3整合了两项建议:

to example3
  let values [1 2 3]
  let probabilities [0.2 0.3 0.5]
  let pairs (map list values probabilities)
  let state first rnd:weighted-one-of pairs [ last ? ]
end

答案 1 :(得分:3)

如果您想使用任何概率,而不仅仅是那些添加到概率的概率,您可以在没有rnd扩展名的情况下执行此操作。例如,如果您想根据投票数选择候选人1,2或3:

to-report weighted-rand 
  let values [1 2 3]
  ;let probabilities [0.2 0.3 0.5]
  let votes [5 7 9]

  ; calculate the cumulative probability list
  let cum reduce [
    lput (?2 + (ifelse-value (empty? ?1) [0] [last ?1])) ?1
  ] (fput [] votes)

  ; Roll a uniform random number weighted by the cumulative probability vector
  let x random-float sum votes
  let j  -1
  let found false
  while [(not found) and (j < (length cum))]
  [
    set j (j + 1)
    if (x <= item j cum) [set found true]
  ]

  report item j values
end

这有点复杂(特别是使用reduce),但它基本上做的是创建概率(投票)的累积和,然后在该列表中找到统一随机值下降的位置。然后它返回与找到的地点对应的值列表中的项目。