我在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 )
答案 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)
从两个单独的列表中构建对的列表。他还提到,使用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
答案 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),但它基本上做的是创建概率(投票)的累积和,然后在该列表中找到统一随机值下降的位置。然后它返回与找到的地点对应的值列表中的项目。