I have a list in NetLogo with values and a list of probabilities for each value. Now I want to draw a random value based on its probability (weighted random draw). I thought of using the Rnd extension, but I cant quite figure out how to get the weights right, please help
set values [1 2 3]
set probabilities [0.2 0.3 0.5]
set state ( rnd:weighted-one-of agentset reporter-task )
If you want/need to use two separate lists for your values and probabilities, the way to do it is to have the extension pick an index and use this index to access both the probability in the reporter passed to rnd:weighted-one-of
and, once it is chosen, the value in your list. That's example1
in the code below.
The extension is easier to work with, however, if you can put both your values and your probabilities in the same list. This is done by building a list of "pairs" (i.e., a list of lists with two items in each sublist). When you have that, you can use the second item of the pair (item 1
) in the reporter and set your state using the first item of the pair (item 0
). example2
shows how to do this.
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
Edit:
As mentioned by Seth in the comments, you can construct your list of pairs from the two separate lists with (map list values probabilities)
. He also mentions that the code might be "clearer with first
and last
instead of item 0
and item 1
."
example3
integrates both suggestions:
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