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

问题描述 投票:0回答:3

我在 NetLogo 中有一个包含值的列表以及每个值的概率列表。现在我想根据概率抽取一个随机值(加权随机抽取)。我想过使用 Rnd 扩展,但我不太清楚如何获得正确的权重,请帮忙

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

set state ( rnd:weighted-one-of agentset reporter-task )
netlogo
3个回答
4
投票

如果您想使用 any 概率,而不仅仅是那些加起来为 1 的概率,您可以在不使用 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

这有点复杂(尤其是减少的棘手使用),但它基本上所做的是创建概率(投票)的累积和,然后找到该列表中均匀随机值下降的位置。然后它从与找到的位置相对应的值列表中返回该项目。


3
投票

如果您想要/需要为您的值和概率使用两个单独的列表,则方法是让扩展程序选择一个 index 并使用该索引来访问传递给

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)
从两个单独的列表构建配对列表。他还提到,代码可能“使用
first
last
而不是
item 0
item 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

0
投票

基于 theoden 的答案,这里有一个适应较新的 NetLogo reduce 语法的版本:

to-report weighted-rand [ values votes ]
  
  ; Calculate the cumulative probability list
  let cum reduce [ [ acc curr ] -> lput (curr + (ifelse-value (empty? acc) [0] [ last acc ])) acc ] (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
© www.soinside.com 2019 - 2024. All rights reserved.