Esempio n. 1
0
        public ActionResult ComputeErlangC(long numberOfCalls, long ahtInSeconds, decimal requiredServiceLevel,
                                           long targetAnswerTimeInSeconds, decimal shrinkage)
        {
            string msg = string.Empty;

            ErlangCViewModel erlangModel = new ErlangCViewModel();

            try
            {
                erlangModel = _erlangService.Calculate(numberOfCalls, ahtInSeconds, requiredServiceLevel, targetAnswerTimeInSeconds, shrinkage);
            }
            catch (Exception ex)
            {
                msg = ex.Message;
            }
            ErlangCCalculatorResult model = new ErlangCCalculatorResult()
            {
                ErlangCViewModel = erlangModel,
                Message          = msg
            };

            return(Json(model, JsonRequestBehavior.AllowGet));
        }
Esempio n. 2
0
        public ErlangCViewModel Calculate(long numberOfCalls, long ahtInSeconds, decimal requiredServiceLevel,
                                          long targetAnswerTimeInSeconds, decimal shrinkage, long?newN = null)
        {
            ErlangCViewModel model = new ErlangCViewModel();

            #region Declare Variable(s)

            long    a = 0;
            long    n = 0;
            long    numberOfCallsPerHour = 0;
            decimal x      = 0;
            decimal y      = 0;
            decimal pw     = 0;
            decimal pwPerc = 0;
            decimal sl     = 0;
            decimal slPerc = 0;
            decimal asa    = 0;
            decimal immediateAnswerPerc    = 0;
            decimal occupancyPerc          = 0;
            long    numberOfAgentsRequired = 0;

            #endregion Declare Variable(s)

            #region 2. Work Out the Number of Calls Per Hour

            numberOfCallsPerHour = numberOfCalls;

            #endregion 2. Work Out the Number of Calls Per Hour

            #region 3. Work Out the Traffic Intensity (A)

            long ahtInMinutes = ahtInSeconds / 60;
            a = (numberOfCalls * ahtInMinutes) / 60;

            #endregion 3. Work Out the Traffic Intensity (A)

            #region 4. Estimate the Raw Number of Agents Required (N)

            //Initial value is A+1
            if (newN == null)
            {
                n = (a + 1);
            }
            else
            {
                n = (long)newN;
            }

            //n = newN ?? (a+1);

            #endregion 4. Estimate the Raw Number of Agents Required (N)

            //	--5.Calculate the Erlang Formula for Probability a Call Waits(SKIP)
            //   --6.Work Out N!(N Factorial) (SKIP)
            // --7.Be Careful With Large Factorials (SKIP)
            //--                           n
            //--8.Work Out the Powers – A(SKIP)
            //--9.Let’s Simplify the Erlang C Formula
            //--       X  / (Y + X)

            #region 10. Let’s Work Out the Top Row of the Erlang Formula (X)

            //			--NUMERATOR FIRST(X)
            //--   n
            //-- A* N
            //	--___       ___
            //	-- N!N-A
            decimal numeratorA, numeratorB;

            numeratorA = (decimal)Math.Pow(a, n) / this.Factorial(n);
            numeratorB = (decimal)n / ((decimal)n - (decimal)a);
            x          = numeratorA * numeratorB;

            #endregion 10. Let’s Work Out the Top Row of the Erlang Formula (X)

            #region 11. Work Out the Sum of a Series (Y) or ΣApowerofI/i!

            //loop n
            decimal       i = 0;
            decimal       eaPowOfiDivIFact = 0;
            List <TableY> tblY             = new List <TableY>();

            while (i <= (n - 1))
            {
                decimal iFact, aPowI, aPowOfiDivIFact;

                iFact            = i == 0 ? 1 : this.Factorial(i);
                aPowI            = (decimal)Math.Pow(a, (double)i);
                aPowOfiDivIFact  = aPowI / iFact;
                eaPowOfiDivIFact = eaPowOfiDivIFact + aPowOfiDivIFact;

                tblY.Add(new TableY()
                {
                    i          = i,
                    iFactorial = iFact,
                    aPowerOfi  = aPowI,
                    aPowerOfiDivideIFactorial      = aPowOfiDivIFact,
                    SumOfAPowerofIDivideIFactorial = eaPowOfiDivIFact
                });

                i++;
            }

            y = tblY.OrderByDescending(s => s.SumOfAPowerofIDivideIFactorial).FirstOrDefault().SumOfAPowerofIDivideIFactorial;

            #endregion 11. Work Out the Sum of a Series (Y) or ΣApowerofI/i!

            #region 12. Put X and Y into the Erlang C Formula (The probability a call has to wait)

            pw     = x / (x + y);
            pwPerc = pw * 100;

            #endregion 12. Put X and Y into the Erlang C Formula (The probability a call has to wait)

            #region 13. Calculate the Service Level

            #region 13.1 Let’s work out -(N – A) * (TargetTime / AHT)

            double exponent = 0;
            exponent = -((n - a) * ((double)targetAnswerTimeInSeconds / (double)ahtInSeconds));

            #endregion 13.1 Let’s work out -(N – A) * (TargetTime / AHT)

            sl     = 1 - (pw * (decimal)Math.Exp(exponent));
            slPerc = sl * 100;

            if (slPerc < requiredServiceLevel)
            {
                long nIncrement = n + 1;
                model = this.Calculate(numberOfCalls, ahtInSeconds, requiredServiceLevel, targetAnswerTimeInSeconds, shrinkage, nIncrement);
            }
            else
            {
                #region 15.  Average Speed of Answer (ASA)

                //ASA = Pw(AHT)/(No.of Agents-Traffic Intesity)
                asa = (pw * ahtInSeconds) / (n - a);

                #endregion 15.  Average Speed of Answer (ASA)

                #region 16. Percentage of Calls Answered Immediately

                //Immediate Answer = (1-Pw)x100
                immediateAnswerPerc = (1 - pw) * 100;

                #endregion 16. Percentage of Calls Answered Immediately

                #region 17. Check Maximum Occupancy

                //Occupancy = (([TrafficIntensity or A])/[RawAgents or N] )* 100
                occupancyPerc = ((decimal)a / (decimal)n) * 100;
                if (occupancyPerc > 85)
                {
                    occupancyPerc = (decimal)a / (occupancyPerc / 100);
                }

                #endregion 17. Check Maximum Occupancy

                #region 18. Factor In Shrinkage

                //DECLARE @ShrinkagePerc NUMERIC(18,3) = 30 --The industry average is around 30–35%, in this case we used 30%. Note that we can change it
                //NumberOfAgentsRequired = [Raw Agents or N]/(1-(Shrinkage/100))
                numberOfAgentsRequired = (long)Math.Ceiling((decimal)n / (1 - (shrinkage / 100)));

                #endregion 18. Factor In Shrinkage

                model.NumberOfAgentsRequired = numberOfAgentsRequired;
                model.ServiceLevel           = sl;
                model.ServiceLevelPerc       = Math.Round(slPerc, 2);
                model.PwErlang                 = pw;
                model.PwErlangPerc             = Math.Round(pwPerc, 2);
                model.ASA                      = Math.Round(asa, 2);
                model.ImmediateAnswerPerc      = Math.Round(immediateAnswerPerc, 2);
                model.TargetAnswerTimeInSecond = targetAnswerTimeInSeconds;
                model.AHTSec                   = ahtInSeconds;
                model.RequiredServiceLevelPerc = Math.Round(requiredServiceLevel, 2);
                model.N             = n;
                model.X             = x;
                model.Y             = y;
                model.A             = a;
                model.OccupancyPerc = Math.Round(occupancyPerc, 2);
            }

            #endregion 13. Calculate the Service Level

            return(model);
        }