Wednesday, March 12, 2014

Erlang-C formula in Maxima

Let's express some well-known formulas for service waiting time, for which telephone calls are a commonly-used example. Discussion here is based on a web page [1] which states the formulas. I'll just copy the formulas verbatim and show how Maxima can carry out some interesting operations with them. I've posted the script "erlang.mac" which contains the function definitions. [2]

[1] The Erlang-C Formula
[2] erlang.mac

As with other articles about worked examples, I'm including only the barest outline and omitting a lot of details. If you're interested, we can follow up in the comments.

Preliminaries

The erlang.mac script makes use of a couple of Maxima add-ons, namely "namespaces" and "ezunits". It puts the functions it defines in a namespace "erlang" so I'll write "erlang|E_c" to refer to the function E_c in the namespace erlang. Also, the script assumes that quantities (e.g., time) come with units attached.

fpprintprec : 4 $
batch ("./erlang.mac") $

Numerical examples

Let's reproduce the examples from the web page. First let's compute E_c for a given lambda, T_s, and m.

erlang|E_c (0.2 ` call/s, 240 ` s/call, 55);
0.2387

Let's evaluate T_w, the expected waiting time, for given parameters.

erlang|T_w (0.2 ` call/s, 240 ` s/call, 55);
8.184 s call

Let's compute the probability that waiting time is less than or equal to 15 seconds.

erlang|W (0.2 ` call/s, 240 ` s/call, 55, 15 ` s/call);
0.8459

Symbolic operations

So far, so good; the numerical values agree with those stated on the web page. Let's look at some symbolic operations. If some parameters are unknown, the functions return expressions in the unknown parameters. Given fixed values for call intensity and number of agents, how does expected waiting time vary as a function of the average call duration?

foo : erlang|T_w (0.2 ` call/s, T_s ` s/call, 4);
1.6667·10 -5T_s5 ( 1- 0.05T_s ) ( 6.6667·10 -5T_s4 + ( 1- 0.05T_s ) ( 0.001333T_s3 + 0.02T_s2 + 0.2T_s +1 ) ) s call

Notice that T_w is undefined for (number of agents)/(call intensity) ≥ 1. As that ratio approaches 1 from below, the expected waiting time increases without bound.

plot2d (qty (foo), [T_s, 0, 4/0.2], [y, 0, 100]);
Produced by GNUPLOT 4.4 patchlevel 3 T_s 0 20 40 60 80 100 0 5 10 15 20

Likewise, the function P(waiting time ≤ t) is a function of t alone given other parameters.

erlang|W (0.2 ` call/s, 240 ` s/call, 55, t ` s/call);
1- 0.2387 - 0.02917t

Let's construct a function which takes just t as an argument. The other parameters are baked in.

W (t) := ''(erlang|W (0.2 ` call/s, 240 ` s/call, 55, t ` s/call));
W (t) := ( 1- 0.2387 - 0.02917t )

Let's take a look at that function W.

plot2d (W, [t, 0, 50]);
Produced by GNUPLOT 4.4 patchlevel 3 W t 0.76 0.78 0.8 0.82 0.84 0.86 0.88 0.9 0.92 0.94 0.96 0 10 20 30 40 50

Another way to approach this is to construct a lambda expression (anonymous function).

foo (a, b, c) :=
buildq ([a, b, c], lambda ([t], erlang|W (a, b, c, t ` s/call)));
foo (a,b,c) :=buildq ([a,b,c],λt.W (a,b,c, t s call ) )
bar : foo (0.2 ` call/s, 240 ` s/call, 55);
λt.W ( 0.2 call s , 240 s call ,55, t s call )
bar (15);
0.8459

Finally, let's construct a memoizing function (called an "array function" in Maxima). We can think of this as a family of functions of t which are indexed by the parameters.

baz [%lambda, T_s, m] (t) :=
erlang|W (%lambda ` call/s, T_s ` s/call, m, t ` s/call);
baz %lambda,T_s,m (t) :=W ( %lambda call s , T_s s call ,m, t s call )
baz [0.2, 240, 55];
λt. 1- 0.2387 - 0.02917t
baz [0.2, 240, 55] (15);
0.8459

That's it for now.

build_info();
branch_5_32_base_34_g7259ab3 2014-03-07 16:22:33 i686-pc-linux-gnu CLISP 2.49 (2010-07-07) (built 3539704948) (memory 3603226955)

1 comment: