jwalpole Posted January 10, 2012 Share Posted January 10, 2012 Okay so I was scouring the web looking for PHP examples of ways to use php to get an estimation of wait time my customers would have to wait for my service technicians to get their location. I found Erlang C Equation. I then looked for php examples on the web and had no luck. So for anyone who is interested, here is my code based on the erlang C Equation found at http://www.had2know.com/technology/erlang-c-formula-calculator.html /** * Erlang C formlua based on equation from http://www.had2know.com/technology/erlang-c-formula-calculator.html * */ /** * * @param unknown_type $T Average Minutes per call * @param unknown_type $C Number of Calls per day */ function Erlangs($T=900, $C=20){ $seconds_in_a_day = 86400;//static variable //Get number of Erlangs $E1 = $seconds_in_a_day/($T);//$minutes per call * 60 to get seconds $E = $C/$E1; return $E; } /** * @param $E Number of Erlangs * @param $N Sigma formula Start number * @param $M number of trunks/phone lines * @param $C Number of Calls per day * @param $T Average minutes spent per call in seconds. */ function ErlangCProbabilityOfWait($E, $N=0,$M=2,$C=20,$T=900){ //try to mimic the mathematical sigma function //where when a zero appears that is factored and evaluated as 1 and then use the real 1. for($N=0;$N<=$M-1;$N++){ $sigma_formula += bcpow($E,$N,4)/gmp_strval(gmp_fact($N)); } //get queued wait period/probability queued $Pqueued_wait = (bcpow($E,$M,4)/gmp_strval(gmp_fact($M))) / ( (bcpow($E,$M,4)/gmp_strval(gmp_fact($M))) + (1-$E/$M)*$sigma_formula ); return $Pqueued_wait; } /** * * @param unknown_type $T Average minutes spent per call in seconds. * @param unknown_type $Pqueued_wait Probability of call being placed in wait queue * @param unknown_type $M number of trunks/phone lines * @param unknown_type $E Number of Erlangs */ function ErlangCWaitTime($T,$Pqueued_wait,$M,$E){ //now that the above equation works we can estimate wait time ASA // ASA = (T*Pqueued)/(M-E) $ASA = ($T*$Pqueued_wait)/($M-$E); echo round($ASA,1) . ' Seconds';//return value in seconds //if value is over 60 seconds display minutes. } $Average_call_time_in_seconds = 900; $Calls_per_day = 480; $Number_of_phone_lines = 10; $Sigma_formula_Start_number = 0; //number of erlangs $Erlangs = Erlangs($Average_call_time_in_seconds,$Calls_per_day); //probability of Wait $Probability_of_wait = ErlangCProbabilityOfWait($Erlangs, $Sigma_formula_Start_number, $Number_of_phone_lines, $Calls_per_day, $Average_call_time_in_seconds); // echo ErlangCWaitTime($Average_call_time_in_seconds, $Probability_of_wait, $Number_of_phone_lines, $Erlangs); This works but I need to modify to calculate mileage and travel time. Any thoughts. Quote Link to comment Share on other sites More sharing options...
jwalpole Posted January 11, 2012 Author Share Posted January 11, 2012 Since I posted yesterday, I decided that this would probably be best if put into a class. So I rewrote it. Please feel free to critique and let me know what your thoughts are? if there is something I missed, etc. let me know. class EstimatedWaitTime{ /** * Erlang C formlua based on equation from http://www.had2know.com/technology/erlang-c-formula-calculator.html * P<sub>queued</sub> = (E<sup>M</sup>/M!)/[E<sup>M</sup>/M! + (1-E/M) Σ <sup>M-1</sup><sub>n=0</sub> E<sup>n</sup>/n!] * ASA = Average Speed of Answer * ASA = (T*P<sub>queued</sub>)/(M-E); */ public $Ti; //9.5hrs in seconds - Total time to calculate erlang public $T; //Average_call_time_in_seconds - 900 seconds is 15 minutes maybe include travel time??? public $C; //calls per day public $M; //Number_of_phone_lines public $N; //Sigma_formula_Start_number public $Pqueued_wait; public $E; //Erlangs public function __construct($Ti,$T,$C,$M,$N){ $this->T = $T; $this->Ti = $Ti; $this->C = $C; $this->M = $M; $this->N = $N; //$this->Pqueued_wait = $Pqueued_wait; //$this->E = $E; } /** * * @param $T Average Minutes per call * @param $C Number of Calls per day * @param $Ti total time interval in seconds default is 24hrs (86400 seconds) */ public function Erlangs(){ // Erlangs are The usage time for all resources that are divided by the total time interval. //Get number of Erlangs $E1 = $this->Ti/($this->T);//$minutes per call * 60 to get seconds $E = $this->C/$E1; $this->E = $E; return $this->E; } /** * @param $E Number of Erlangs * @param $N Sigma formula Start number * @param $M number of trunks/phone lines * @param $C Number of Calls per day * @param $T Average minutes spent per call in seconds. */ public function ErlangCProbabilityOfWait(){ $sigma_formula = ''; //try to mimic the mathematical sigma function //where when a zero appears that is factored and evaluated as 1 and then use the real 1. for($this->N=0; $this->N <= ($this->M) - 1; $this->N++){ $sigma_formula += bcpow($this->E,$this->N,4)/gmp_strval(gmp_fact($this->N)); } //get queued wait period/probability queued $Pqueued_wait = (bcpow($this->Erlangs(),$this->M,4) / gmp_strval(gmp_fact($this->M))) / ( (bcpow($this->Erlangs(),$this->M,4) / gmp_strval(gmp_fact($this->M))) + (1-$this->Erlangs()/$this->M)*$sigma_formula ); $this->Pqueued_wait = $Pqueued_wait; return $this->Pqueued_wait; } /** * * @param unknown_type $T Average minutes spent per call in seconds. * @param unknown_type $Pqueued_wait Probability of call being placed in wait queue * @param unknown_type $M number of trunks/phone lines * @param unknown_type $E Number of Erlangs */ public function ErlangCWaitTime(){ //now that the above equation works we can estimate wait time ASA // ASA = (T*Pqueued)/(M-E) $ASA = ($this->T*$this->ErlangCProbabilityOfWait())/($this->M - $this->Erlangs()); //if value is over 60 seconds display minutes. if($ASA > 60){ $ASA = round(($ASA/60),1) . ' Minutes'; } else { $ASA = round($ASA,1) . ' Seconds'; } return $ASA; } } echo 'P<sub>queued</sub> = (E<sup>M</sup>/M!)/[E<sup>M</sup>/M! + (1-E/M) Σ <sup>M-1</sup><sub>n=0</sub> E<sup>n</sup>/n!]<br /><br />'; $suffolkEWT = new EstimatedWaitTime(86400,900,480,10,0); //$EWT->ErlangCWaitTime(); echo 'Suffolk Erlangs Needed: ' . $suffolkEWT->Erlangs() .'<br />'; echo 'Suffolk Probability of Wait: ' . $suffolkEWT->ErlangCProbabilityOfWait() . '<br />'; echo 'Suffolk EWT: ' . $suffolkEWT->ErlangCWaitTime() . '<br /><br />'; Quote Link to comment Share on other sites More sharing options...
SergeiSS Posted January 11, 2012 Share Posted January 11, 2012 I'm very familiar with Erlang C formula (I'm programmer at GSM/3G operator). And I know 2 versions. Even if I know it it's difficult to understand your question. BTW use php tags instead of code tags. It will highlight PHP code About programming. You wrote $sigma_formula = ''; You'd better write $sigma_formula = 0; because you use it later in the mathematical equations. Quote Link to comment Share on other sites More sharing options...
jwalpole Posted January 11, 2012 Author Share Posted January 11, 2012 Sergie, thanks for the recommendations. I am trying to modify this equation for my company. We send techs out in vehicles to make service calls. I need to try and include travel time, as well as avg time it takes to complete call and get to next call in this equation. There can be multiple calls at one location as well. I believe on way of doing it is to add the time in seconds to the average call time but I did that and get 5 seconds and with travel time from site to site I have to be missing something. I am sure it is staring at me right in the face but, I just can't see it. Quote Link to comment Share on other sites More sharing options...
jwalpole Posted January 11, 2012 Author Share Posted January 11, 2012 Sergie, here is an example require ('ErlangWaitTime.class.php'); $number_of_nassau_techs = numberOfTechs(105, 1);//get number of techs assigned from database $number_of_suffolk_techs = numberOfTechs(105, 2);//get number of techs assigned from database $nassau_service_calls = 0; $suffolk_service_calls = 0; for($n=0; $n<=count($just_service_calls_array); $n++){ if( $just_service_calls_array[$n]['assoc'] == '1'){ $nassau_service_calls++; } } for($n=0; $n<=count($just_service_calls_array); $n++){ if($just_service_calls_array[$n]['assoc'] == '2'){ $suffolk_service_calls++; } } $time_interval_in_seconds = 34200; //set for a 9.5 hour day $Average_nassau_call_time_in_seconds = 1900; //adjust dynamically with Db query based on prev month include travel time and currently assigned calls $Average_suffolk_call_time_in_seconds = 1900; //adjust dynamically with Db query based on prev month include travel time and currently assigned calls $avg_nassau_calls_per_day = 6.6; //adjust dynamically with Db query based on prev month numbers $avg_suffolk_calls_per_day = 4.7; //adjust dynamically with Db query based on prev month numbers //estimated wait time per call $NEWT = new EstimatedWaitTime($time_interval_in_seconds, $Average_nassau_call_time_in_seconds, $avg_nassau_calls_per_day, $number_of_nassau_techs, 0); $NCEWT = $NEWT->ErlangCWaitTime(); $NCEWT = $NCEWT*$nassau_service_calls; $SEWT = new EstimatedWaitTime($time_interval_in_seconds, $Average_suffolk_call_time_in_seconds, $avg_suffolk_calls_per_day, $number_of_suffolk_techs, 0); $SCEWT = $SEWT->ErlangCWaitTime(); $SCEWT = $SCEWT*$suffolk_service_calls; if($NCEWT > 60){ $NCEWT = round($NCEWT/60,0) . ' Minutes'; //take the seconds and divide by 60 to get minutes } else { $NCEWT = round($NCEWT,0) . ' Seconds'; } if($SCEWT > 60){ $SCEWT = round($SCEWT/60,0) . ' Minutes'; //take the seconds and divide by 60 to get minutes } else { $SCEWT = round($SCEWT,0) . ' Seconds'; } Now with that if I have 2 calls and 2 techs in Nassau EWT is 3 seconds! Which in this case the sites are about 10 miles apart. I am currently going to modify some things so that it only uses unassigned calls, but I still have the issue with distance. Quote Link to comment Share on other sites More sharing options...
jwalpole Posted January 11, 2012 Author Share Posted January 11, 2012 Here I added the GoS (Grade of Service Function) to the class for no other reason than to have it. /** * Created By: John Walpole Jr * Version: 1.1 * * Description: * Erlang C formlua based on equation from http://www.had2know.com/technology/erlang-c-formula-calculator.html * P<sub>queued</sub> = (E<sup>M</sup>/M!)/[E<sup>M</sup>/M! + (1-E/M) Σ <sup>M-1</sup><sub>n=0</sub> E<sup>n</sup>/n!] * ASA = Average Speed of Answer * ASA = (T*P<sub>queued</sub>)/(M-E); * example: * $suffolkEWT = new EstimatedWaitTime(86400,900,480,10,0); * echo 'Suffolk Erlangs Needed: ' . $suffolkEWT->Erlangs() .'<br />'; * echo 'Suffolk Probability of Wait: ' . $suffolkEWT->ErlangCProbabilityOfWait() . '<br />'; * echo 'Suffolk EWT: ' . $suffolkEWT->ErlangCWaitTime() . '<br /><br />'; */ class EstimatedWaitTime{ public $Ti; //9.5hrs in seconds - Total time to calculate erlang public $T; //Average_call_time_in_seconds - 900 seconds is 15 minutes maybe include travel time??? public $C; //calls per day public $M; //Number_of_phone_lines public $N; //Sigma_formula_Start_number public $Pqueued_wait; public $E; public function __construct($Ti,$T,$C,$M,$N){ $this->T = $T; $this->Ti = $Ti; $this->C = $C; $this->M = $M; $this->N = $N; } /** * * @param $T Average Minutes per call * @param $C Number of Calls per day * @param $Ti total time interval in seconds default is 24hrs (86400 seconds) */ public function Erlangs(){ // Erlangs are The usage time for all resources that are divided by the total time interval. //Get number of Erlangs $E1 = $this->Ti/($this->T);//$minutes per call $E = $this->C/$E1; $this->E = $E; return $this->E; } /** * @param $E Number of Erlangs * @param $N Sigma formula Start number * @param $M number of trunks/phone lines * @param $C Number of Calls per day * @param $T Average minutes spent per call in seconds. */ public function ErlangCProbabilityOfWait(){ $sigma_formula = 0; //try to mimic the mathematical sigma function //where when a zero appears that is factored and evaluated as 1 and then use the real 1. for($this->N=0; $this->N <= ($this->M) - 1; $this->N++){ $sigma_formula += bcpow($this->E,$this->N,4)/gmp_strval(gmp_fact($this->N)); } //get queued wait period/probability queued $Pqueued_wait = (bcpow($this->Erlangs(),$this->M,4) / gmp_strval(gmp_fact($this->M))) / ( (bcpow($this->Erlangs(),$this->M,4) / gmp_strval(gmp_fact($this->M))) + (1-$this->Erlangs()/$this->M)*$sigma_formula ); $this->Pqueued_wait = $Pqueued_wait; return $this->Pqueued_wait; } /** * * @param unknown_type $T Average minutes spent per call in seconds. * @param unknown_type $Pqueued_wait Probability of call being placed in wait queue * @param unknown_type $M number of trunks/phone lines * @param unknown_type $E Number of Erlangs */ public function ErlangCWaitTime(){ //now that the above equation works we can estimate wait time ASA // ASA = (T*Pqueued)/(M-E) $ASA = ($this->T*$this->ErlangCProbabilityOfWait())/($this->M - $this->Erlangs()); //if value is over 60 seconds display minutes. if($ASA > 60){ $ASA = round(($ASA/60),1) . ' Minutes'; } else { $ASA = round($ASA,1) . ' Seconds'; } return $ASA; } /** * Grade of Service function */ public function GoS(){ $gos_sigma_formula = 0; //try to mimic the mathematical sigma function //where when a zero appears that is factored and evaluated as 1 and then use the real 1. for($this->N=0; $this->N <= ($this->M); $this->N++){ $gos_sigma_formula += bcpow($this->Erlangs(),$this->N,4)/gmp_strval(gmp_fact($this->N)); } $GoS = bcpow($this->Erlangs(), $this->M )/gmp_strval(gmp_fact($this->M)) / ($gos_sigma_formula); $GoS = $GoS*100 ;//gets percent return round($GoS,2) . '% of Calls get dropped'; } } I have determined that to find out how long of a wait for unanswered service calls I need to: *count how many calls each tech already has assigned to them *Then for each call at the site multiply that by avg. time call takes to complete *Then I need to total ETAs of closest tech, found by GPS, to site into the AVG call time Does that sound about right? Quote Link to comment Share on other sites More sharing options...
SergeiSS Posted January 12, 2012 Share Posted January 12, 2012 You see... I don't like to go deep into your thoughts... But I can help you in another way. If you like I can send you my own Erlang calculator (EXE file). If you find it useful I can give you the code - it's written in C+++Builder. You may rewrite it in PHP, it's easy to do Give me you e-mail. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.