I'd like to write up something that will generate random numbers that would plot into a triangle distribution. I know how to get a normal distribution, which is similar.

import random

for i in range(200):
  print random.normalvariate(3,1)

But there doesn't seem to be anything in the random module about triangle distribution. Does anyone know of a way to do it?

8 Years
Discussion Span
Last Post by mn_kthompson

I think you could write your own function like this

from random import random
from math import sqrt

def triangular(a, c, b):
  c = float(c)
  t = (c-a)/(b-a)
  y = sqrt(random())
  d = a if random() < t else b
  return d + (c-d) * y

if __name__ == "__main__":
  for i in range(100):
    print(triangular(1, 3, 4))

Explanation: I start from the density function in the wikipedia page http://en.wikipedia.org/wiki/Triangular_distribution. Obviously, if a random variable Z has this distribution, the probability that it's between a and c is t=(c-a)/(b-a). So I first choose if the variable must be between a and c or between c and b by comparing a uniformly random number in [0,1] to this value. Then I choose a first Y which is the square root of a uniformly random number between 0 and 1. Such a variable has a linear density function f(t) = 2 t in (0, 1]. This is easy to compute. Then I rescale this variable so that it falls between [a, c] or [c, b].
There is some work if you want to convince yourself that it works, but I'm rather good at math, so it should :)


Obviously, if a random variable Z has this distribution, the probability that it's between a and c is t=(c-a)/(b-a).

Oh yeah, that's totally obvious. I'm not exactly bad at math, but I never would have derived that from the probability density formula given. I thought I would have to take in my random number, test if the random number was between a and c or if it was between c and b. It looks like you're doing that on lines 6 and 8, but I don't understand it. I'll call that the magic part. Then I figured I would apply that 2(x-a)/(b-a)(c-a) formula that was given. I never would have thought about rescaling it back.

Then I said "Aw hell, maybe there's a built in way to do it."


By the way, I ran your function 1000 times with a lower bound of 1, an upper bound of 4 and a most likely number of 3. I then plotted the number in Excel and have attached the graph. It is quite triangular.

Votes + Comments
thanks for the test.
Attachments triangle.jpg 51.5 KB
This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.