Created
September 18, 2018 15:31
-
-
Save rekyuu/7a35756f05a60e1223abf0f4896b9da3 to your computer and use it in GitHub Desktop.
Elixir ErlangC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule ErlangC do | |
def factorial_of(0), do: 1 | |
def factorial_of(n) when n > 0, do: n * factorial_of(n - 1) | |
def traffic_intensity(calls, reporting_period, average_handle_time) do | |
calls_per_hour = (60 / reporting_period) * calls | |
(calls_per_hour * (average_handle_time / 60)) / 60 | |
end | |
def probability_call_waits(traffic_intensity, agents) do | |
numerator = (:math.pow(traffic_intensity, agents) / factorial_of(agents)) * (agents / (agents - traffic_intensity)) | |
sigma = Enum.map(0..(agents - 1), fn(i) -> | |
:math.pow(traffic_intensity, i) / factorial_of(i) | |
end) |> Enum.sum | |
denominator = sigma + numerator | |
numerator / denominator | |
end | |
def service_level(traffic_intensity, agents, target_answer_time, average_handle_time) do | |
1 - (probability_call_waits(traffic_intensity, agents) * :math.exp(-((agents - traffic_intensity) * (target_answer_time / average_handle_time)))) | |
end | |
def average_speed_of_answer(average_handle_time, agents, traffic_intensity) do | |
(probability_call_waits(traffic_intensity, agents) * average_handle_time) / (agents - traffic_intensity) | |
end | |
def raw_agents_needed(traffic_intensity, target_answer_time, average_handle_time, required_service_level) do | |
agents = Kernel.trunc(traffic_intensity + 1) | |
Enum.reduce_while(1..(255 - agents), agents, fn (i, acc) -> | |
service_level = ErlangC.service_level(traffic_intensity, acc, target_answer_time, average_handle_time) | |
if service_level < required_service_level do | |
{:cont, acc + i} | |
else | |
{:halt, acc} | |
end | |
end) |> Kernel.trunc | |
end | |
def agents_needed(traffic_intensity, target_answer_time, average_handle_time, required_service_level, shrinkage) do | |
Kernel.trunc(raw_agents_needed(traffic_intensity, target_answer_time, average_handle_time, required_service_level) / (1 - shrinkage)) | |
end | |
end | |
defmodule Factorial do | |
def of(0), do: 1 | |
def of(n) when n > 0, do: n * of(n - 1) | |
end | |
calls = 100 | |
reporting_period = 30.0 # in minutes | |
average_handle_time = 180.0 # in seconds | |
required_service_level = 0.80 | |
target_answer_time = 20.0 # in seconds | |
shrinkage = 0.30 | |
traffic_intensity = ErlangC.traffic_intensity(calls, reporting_period, average_handle_time) | |
raw_agents_needed = ErlangC.raw_agents_needed(traffic_intensity, target_answer_time, average_handle_time, required_service_level) | |
agents_needed = ErlangC.agents_needed(traffic_intensity, target_answer_time, average_handle_time, required_service_level, shrinkage) | |
service_level = Float.round(ErlangC.service_level(traffic_intensity, raw_agents_needed, target_answer_time, average_handle_time) * 100, 2) | |
call_wait_probability = Float.round(ErlangC.probability_call_waits(traffic_intensity, raw_agents_needed) * 100, 2) | |
asa = Float.round(ErlangC.average_speed_of_answer(average_handle_time, raw_agents_needed, traffic_intensity), 2) | |
IO.puts "Raw agents required: #{raw_agents_needed}" | |
IO.puts "Agents required (with shrinkage): #{agents_needed}" | |
IO.puts "Service level: #{service_level}%" | |
IO.puts "Probability a call has to wait: #{call_wait_probability}%" | |
IO.puts "Average Speed of Answer: #{asa}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment