Skip to main content

Distributions

Any unfamiliar word is in the glossary.

Every duration in a model is a distribution: how long a step takes, the gap between arrivals, time to repair, how long a break lasts. They all share one shape.

kind: exponential
mean: 120.0

kind selects the family and the remaining keys are its parameters. All values are seconds unless the field says otherwise.

The seven kinds, drawn​

Every picture below is a histogram of 200,000 draws taken the way the engine takes them, and every one has the same mean of 90 seconds. What differs is the spread — and the spread is the whole reason to run a simulation.

constant​

constant distribution
kind: constant
value: 90

Always the same. A repeatable machine cycle. Zero is legal for a process time and means an instantaneous step; zero is not legal as an interarrival time.

exponential​

exponential distribution
kind: exponential
mean: 90.0

Memoryless: most draws are short, a few are very long. The default choice for arrivals and for unplanned failures. Note the tail — it runs well past three times the mean.

uniform​

uniform distribution
kind: uniform
lo: 40.0
hi: 140.0

Flat between the bounds. Honest when all you know is a range.

uniform_offset​

uniform offset distribution
kind: uniform_offset
mean: 90.0
offset: 35.0

The same shape written as a centre and a half-width, which is how SMT2020 and several other datasets express it. mean - offset may not go below zero.

triangular​

triangular distribution
kind: triangular
lo: 40.0
mode: 75.0
hi: 160.0

Peaked at mode. Use it when somebody can give you a best case, a worst case and a usual case — which is most of the time, on a shop floor.

normal​

rectified normal distribution
kind: normal
mean: 90.0
sd: 28.0
rectify: true
Look at the left edge

That is rectify: true clamping at zero. Without it the distribution would produce negative durations, and validate refuses the model when mass falls below zero rather than letting a step take minus four seconds. It is an error, not a warning: cwright validate exits 1.

erlang​

Three k values, same mean. k is how repeatable the thing is.

erlang k=2 erlang k=8 erlang k=32
kind: erlang
k: 2
mean: 90.0
kind: erlang
k: 8
mean: 90.0
kind: erlang
k: 32
mean: 90.0

At k = 1 an Erlang is an exponential. As k rises it tightens towards a constant, which makes it the natural way to say "repeatable, but not perfectly so".

Same mean, different plant​

Measured from the draws above:

kindmeansdcvqueue, relative to exponential
constant90.0 s0.0 s0.0000.50×
erlang k=3290.0 s15.9 s0.1770.52×
uniform_offset90.0 s20.2 s0.2250.53×
triangular91.6 s25.2 s0.2760.54×
normal90.0 s28.0 s0.3110.55×
uniform89.9 s28.9 s0.3210.55×
erlang k=889.9 s31.8 s0.3540.56×
erlang k=290.0 s64.1 s0.7120.75×
exponential90.1 s90.7 s1.0071.00×
This table is the argument for the whole product

Every row has the same average. A capacity sheet cannot tell them apart, because a capacity sheet only knows the mean. The queue in front of the machine differs by a factor of two between the top row and the bottom one, at identical load.

The last column is (1 + cv²) / 2, the Pollaczek–Khinchine result for a single server: the queue scales with the square of the coefficient of variation. Replacing a spread with its mean does not make a model simpler, it makes the model wrong in the optimistic direction.

Choosing one​

  • A machine that repeats — constant, or erlang with a high k. A cell like this queues about half of what a memoryless model predicts, which is why assuming exponential "to be safe" can talk you into capacity you do not need.
  • Unplanned events — failures and repairs are usually exponential.
  • "Best, worst, usually" — triangular.
  • Arrivals you do not control — exponential. Arrivals on a drumbeat — constant.

Every key​

valuemeans
"constant"Always the same value. value is in the unit of the field it sits in, usually seconds.
"exponential"Memoryless, with the given mean. The usual choice for unplanned events and for arrivals.
"uniform"Flat between lo and hi inclusive.
"uniform_offset"The SMT2020 spelling: a mean with a symmetric offset.
"triangular"Peaked at mode, bounded by lo and hi. Useful when somebody can say a best, worst and likely case.
"normal"Gaussian with mean and sd. Set rectify: true to clamp at zero, or validate will refuse the model. Defaults to false.
"erlang"A sum of k exponentials with total mean. Less variable than exponential; k is the shape.
kindkeysconstraints
constantvalue≥ 0
exponentialmean> 0
uniformlo, hi0 ≤ lo ≤ hi
uniform_offsetmean, offsetoffset ≥ 0, mean - offset ≥ 0
triangularlo, mode, hilo ≤ mode ≤ hi, lo < hi
normalmean, sd, rectifysd ≥ 0
erlangk, meank ≥ 1, mean > 0
Regenerating these pictures

scripts/gen-distribution-plots.py draws them from 200,000 samples with a fixed seed, so rerunning it produces byte-identical files and any diff means something really changed.