Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I simulate biased die in python?

I want to simulate N-sided biased die?

def roll(N,bias):
     '''this function rolls N dimensional die with biasing provided'''
     # do something
     return result

>> N=6
>> bias=( 0.20,0.20,0.15,0.15,0.14,0.16,)
>> roll(N,bias)
   2
like image 835
Pratik Deoghare Avatar asked Jan 26 '09 09:01

Pratik Deoghare


3 Answers

It is a little surprising that the np.random.choice answer hasn't been given here.

from numpy import random 
def roll(N,bias):
    '''this function rolls N dimensional die with biasing provided'''
    return random.choice(np.range(N),p=bias)

The p option gives "the probabilities associated with each entry in a", where a is np.range(N) for us. "If not given the sample assumes a uniform distribution over all entries in a".

like image 192
shrokmel Avatar answered Sep 21 '22 08:09

shrokmel


A little bit of math here.

A regular die will give each number 1-6 with equal probability, namely 1/6. This is referred to as uniform distribution (the discrete version of it, as opposed to the continuous version). Meaning that if X is a random variable describing the result of a single role then X~U[1,6] - meaning X is distributed equally against all possible results of the die roll, 1 through 6.

This is equal to choosing a number in [0,1) while dividing it into 6 sections: [0,1/6), [1/6,2/6), [2/6,3/6), [3/6,4/6), [4/6,5/6), [5/6,1).

You are requesting a different distribution, which is biased. The easiest way to achieve this is to divide the section [0,1) to 6 parts depending on the bias you want. So in your case you would want to divide it into the following: [0,0.2), [0.2,0.4), [0.4,0.55), 0.55,0.7), [0.7,0.84), [0.84,1).

If you take a look at the wikipedia entry, you will see that in this case, the cumulative probability function will not be composed of 6 equal-length parts but rather of 6 parts which differ in length according to the bias you gave them. Same goes for the mass distribution.

Back to the question, depending on the language you are using, translate this back to your die roll. In Python, here is a very sketchy, albeit working, example:

import random
sampleMassDist = (0.2, 0.1, 0.15, 0.15, 0.25, 0.15)
# assume sum of bias is 1
def roll(massDist):
    randRoll = random.random() # in [0,1]
    sum = 0
    result = 1
    for mass in massDist:
        sum += mass
        if randRoll < sum:
            return result
        result+=1

print(roll(sampleMassDist))
like image 29
Yuval Adam Avatar answered Nov 15 '22 11:11

Yuval Adam


More language agnostic, but you could use a lookup table.

Use a random number in the range 0-1 and lookup the value in a table:

0.00 - 0.20   1
0.20 - 0.40   2
0.40 - 0.55   3
0.55 - 0.70   4
0.70 - 0.84   5
0.84 - 1.00   6
like image 11
Toon Krijthe Avatar answered Nov 15 '22 12:11

Toon Krijthe