Rebol3 Code Examplex


Probabilistic choice

Given a mapping between items and their required probability of occurrence, generate a million items randomly subject to the given probabilities and compare the target probability of occurrence versus the generated values.

Rebol [
    title: "Rosetta code: Probabilistic choice"
    file:  %Probabilistic_choice.r3
    url:   https://rosettacode.org/wiki/Probabilistic_choice
]

random-choice: function [
    "Return a random item based on weighted probabilities"
    items [map!] "Map of item => probability pairs"
][
    z: random 1.0
    foreach [item prob] items [
        either z < prob [return item][z: z - prob]
    ]
    item ;; return last item as fallback for floating point rounding errors
]

items: make map! reduce [
    'aleph     1 / 5
    'beth      1 / 6
    'gimel     1 / 7
    'daleth    1 / 8
    'he        1 / 9
    'waw       1 / 10
    'zayin     1 / 11
    'heth   1759 / 27720
]
num-trials: 1000000
samples: copy items                          ;; start with same keys
foreach [key v] samples [samples/:key: 0]    ;; zero all counts

loop num-trials [
    key: random-choice items
    samples/:key: samples/:key + 1
]

foreach [item prob] items [
    printf [10 -8 "  " 9.000001 " "][
        item samples/:item  samples/:item / num-trials  prob
    ]
]

Output:

aleph       200413  0.200413  0.2
beth        166301  0.166301  0.166666666666667
gimel       142655  0.142655  0.142857142857143
daleth      125500  0.1255    0.125
he          111258  0.111258  0.111111111111111
waw          99503  0.099503  0.1
zayin        91027  0.091027  0.0909090909090909
heth         63343  0.063343  0.0634559884559885