Skip to content

Instantly share code, notes, and snippets.

@cbaragao
Last active July 9, 2024 11:52
Show Gist options
  • Save cbaragao/472bc0e78e20304154bfc26d32b96cb1 to your computer and use it in GitHub Desktop.
Save cbaragao/472bc0e78e20304154bfc26d32b96cb1 to your computer and use it in GitHub Desktop.
Erlang C calculation in Power Query
let
fnErlangC =
(
number_of_calls as number,
period_of_minutes as number,
average_handling_time as number,
required_service_level as number,
target_answer_time as number,
maximum_occupancy as number,
shrinkage as number
) =>
let
// define probability of waiting function
fnProbWait = (num_agents as number, traffic_intensity as number) =>
let
a_n = Number.Power(traffic_intensity, num_agents),
X = a_n / Number.Factorial(num_agents) * (num_agents / (num_agents - traffic_intensity)),
Y = List.Accumulate(
{0 .. (num_agents - 1)},
0,
(state, current) =>
state + Number.Power(traffic_intensity, current) / Number.Factorial(current)
),
Pw = X / (Y + X)
in
Pw,
// define service level function
fnServiceLevel = (
num_agents as number,
traffic_intensity as number,
prob_waiting as number,
tat as number,
aht as number
) =>
let
ServiceLevel = 1
- (prob_waiting * Number.Exp(- (num_agents - traffic_intensity) * (tat / aht)))
in
ServiceLevel,
// determine calls per hour
calls_per_hour = number_of_calls * 60 / period_of_minutes,
// determine the traffic intensity (A)
A = calls_per_hour * average_handling_time / 3600,
// determine the number of agents (N) - start with A + 1
N = A + 1,
// raise A to the power of N
A_N = Number.Power(A, N),
// determine the probability of waiting
Pw = fnProbWait(N, A),
// determine the service level
SL = fnServiceLevel(N, A, Pw, target_answer_time, average_handling_time),
// iterate until you are N-1 from the target number of agents
Iterate = List.Generate(
() => [Agents = N, Service_Level = SL],
each [Service_Level] < required_service_level,
each [
Agents = [Agents] + 1,
Service_Level = fnServiceLevel(
[Agents] + 1,
A,
fnProbWait([Agents] + 1, A),
target_answer_time,
average_handling_time
)
]
),
// figure out N-1 so you can generate the result next
Last = List.LastN(Iterate, 1){0}[Agents],
// generate the result
Output = [
Agents = Last + 1,
Service_Level = fnServiceLevel(
Last + 1,
A,
fnProbWait(Last + 1, A),
target_answer_time,
average_handling_time
)
]
in
Output,
fnType = type function (
number_of_calls as number,
period_of_minutes as number,
average_handling_time as number,
required_service_level as number,
target_answer_time as number,
maximum_occupancy as number,
shrinkage as number) as record meta
[Documentation.Name = "fnErlangC",
//fnErlangC(100, 30, 180, 0.8, 20, 0.85, 0.3)
Documentation.LongDescription = "This calculates the probable amount of agents needed to meet the required service level and the probable service level for that number of agents in a record.",
Documentation.Examples = {
[Description = "This provides an answer for the following parameters: " &
"Number of Calls = 100; " &
"Period of Minutes = 30; " &
"Average Handling Time (Seconds) = 180; " &
"Required Service Level (% expressed as decimal) = .80; " &
"Target Answer Time (Seconds) = 20; " &
"Maximum Occupancy (% expressed as decimal) = .85; " &
"Shrinkage (% expressed as decimal) = 0.3",
Code = "fnErlangC(100, 30, 180, 0.8, 20, 0.85, 0.3)",
Result="[Agents = 14, Service_Level = 0.888350019]"]
}]
in
Value.ReplaceType(fnErlangC, fnType)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment