//=============================================== file = callCenterNew.c ===== //= A CSIM simulation of a call center with Interactive Voice Response = //============================================================================ //= Notes: Adapted from H. Schwetman, "CSIM17: A Simulation Model-Building = //= Toolkit," Proceedings of the 1994 Winter Simulation Conference, = //= pp. 464-470, 1994. = //=--------------------------------------------------------------------------= //= Sample execution: (callCenterNew 2400 ) = //= = //= ============================================================= = //= == >>>>> CSIM call center simulation with IVR <<<<< == = //= ============================================================= = //= = Simulation time = 2400.000 hours = //= = Call arrival rate = 10.000 calls/min = //= = Call service time = 120.000 sec = //= = Cust max ring time = 20.000 sec = //= = Cust max hold time = 180.000 sec = //= = Number of lines = 10 = //= = Number of ports = 10 = //= = Number of operators = 10 = //= = IVR call service time = 120.000 sec = //= = IVR success prob = 0.500 = //= ============================================================= = //= = CPU time = 1.124 sec = //= ============================================================= = //= &1 Success percentage = 31.885 % = //= &2 Operator utilization = 31.888 % = //= = Total calls = 1438033 = //= = Successful calls = 458521 = //= = Blocked calls = 979502 = //= = Port balks = 0 = //= = Operator balks = 0 = //= = Calls in progress = 10 = //= ============================================================= = //= *** END SIMULATION *** = //= = //=--------------------------------------------------------------------------= //= Execution: callCenter a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 = //= - a1 = Simulation time in hours = //= - a2 = Call_rate in calls per minute = //= - a3 = Serv_time service time in seconds = //= - a4 = Max_ring maximum ring time in seconds = //= - a5 = Max_hold maximum hold time in seconds = //= - a6 = Num_lines number of lines = //= - a7 = Num_ports number of ports = //= - a8 = Num_operators number of operators = //= - a9 = IVR call service time = //= - a10 = IVR success probability = //=--------------------------------------------------------------------------= //= Build: Standard CSIM build = //=--------------------------------------------------------------------------= //= History: KJC (07/05/11) - Genesis (from callCenter.c) = //============================================================================ //----- Includes -------------------------------------------------------------- #include "csim.h" // Needed for CSIM stuff #include // Needed for printf() #include // Needed for atol() and atof() //----- Globals --------------------------------------------------------------- STORE Line; // Lines to be allocated and de-allocated STORE Port; // Ports to be allocated FACILITY Operator; // Operators to be reserved and released double Sim_time; // Simulation run time double Call_rate; // Mean arrival rate of calls per second double Serv_time; // Customer service time in seconds double Max_hold; // Maximum customer hold time in seconds double Max_ring; // Maximum customer ring time in seconds double IVR_serv_time; // IVR call service time double IVR_success; // ICV success proability int Num_act; // Number of actual calls in gen() int Num_calls; // Number of calls in call() int Successful_calls; // Number of successful calls int Operator_balks; // Number of Operator balks int Port_balks; // Number of Port balks int Busy_signals; // Number of busy signals //----- Prototypes ------------------------------------------------------------ void gen(void); // Generate Poisson calls void call(void); // Process calls //============================================================================= //== Main program == //============================================================================= void sim(int argc, char *argv[]) { int num_lines; // Number of lines int num_ports; // Number of ports int num_operators; // Number of operators // Check if enough arguments if (argc != 11) { printf(" Usage is: 'callCenterNew a1 a2 a3 a4 a5 a6 a7 a8 a9 a10': \n"); printf(" - a1 = Simulation time in hours \n"); printf(" - a2 = Call_rate in calls per minute \n"); printf(" - a3 = Serv_time service time in seconds \n"); printf(" - a4 = Max_ring maximum ring time in seconds \n"); printf(" - a5 = Max_hold maximum hold time in seconds \n"); printf(" - a6 = Num_lines number of lines \n"); printf(" - a7 = Num_ports number of ports \n"); printf(" - a8 = Num_operators number of operators \n"); printf(" - a9 = IVR call service time \n"); printf(" - a10 = IVR success probability \n"); exit(1); } // Intialize operational parameters from command line entries Sim_time = atof(argv[1]) * 3600.0; Call_rate = atof(argv[2]) * (1.0 / 60.0); Serv_time = atof(argv[3]); Max_ring = atof(argv[4]); Max_hold = atof(argv[5]); num_lines = atol(argv[6]); num_ports = atol(argv[7]); num_operators = atol(argv[8]); IVR_serv_time = atof(argv[9]); IVR_success = atof(argv[10]); // Create the simulation create("sim"); // Initialize CSIM stuff Line = storage("line", num_lines); Port = storage("port", num_ports); Operator = facility_ms("Operator", num_operators); // Reset all global counters Num_calls = Successful_calls = Operator_balks = Port_balks = Busy_signals = 0; // Output begin-of-simulation banner printf("*** BEGIN SIMULATION *** \n"); // Initiate gen() and hold for Sim_time gen(); hold(Sim_time); // Output results printf("============================================================= \n"); printf("== >>>>> CSIM call center simulation with IVR <<<<< == \n"); printf("============================================================= \n"); printf("= Simulation time = %6.3f hours \n", Sim_time / 3600.0); printf("= Call arrival rate = %6.3f calls/min \n", 60.0 * Call_rate); printf("= Call service time = %6.3f sec \n", Serv_time); printf("= Cust max ring time = %6.3f sec \n", Max_ring); printf("= Cust max hold time = %6.3f sec \n", Max_hold); printf("= Number of lines = %d \n", num_lines); printf("= Number of ports = %d \n", num_ports); printf("= Number of operators = %d \n", num_operators); printf("= IVR call service time = %6.3f sec \n", IVR_serv_time); printf("= IVR success prob = %6.3f \n", IVR_success); printf("============================================================= \n"); printf("= CPU time = %6.3f sec \n", cputime()); printf("============================================================= \n"); printf("&1 Success percentage = %6.3f %% \n", 100.0 * ((double) Successful_calls / Num_calls)); printf("&2 Operator utilization = %6.3f %% \n", 100.0 * util(Operator) / num_operators); printf("= Total calls = %d \n", Num_calls); printf("= Successful calls = %d \n", Successful_calls); printf("= Blocked calls = %d \n", Busy_signals); printf("= Port balks = %d \n", Port_balks); printf("= Operator balks = %d \n", Operator_balks); printf("= Calls in progress = %d \n", (num_lines - avail(Line))); printf("============================================================= \n"); // Output end-of-simulation banner printf("*** END SIMULATION *** \n"); } //============================================================================= //== Function to generate Poisson calls == //============================================================================= void gen(void) { create("gen"); // Loop to create Poisson calls while(1) { call(); hold(expntl(1.0 / Call_rate)); } } //============================================================================= //== Function to process calls == //============================================================================= void call(void) { int port_status; // Timed allocated status for port int oper_status; // Timed reserve status for operator double wait_time; // Computed wait time create("call"); // Increment the number of incoming calls Num_calls++; // Allocate a line if one is available (else a busy signal) if(avail(Line) > 0) { allocate(1, Line); // Timed wait for a port (else a port balk) -- ringing wait_time = uniform(0.0, Max_ring); port_status = timed_allocate(1, Port, wait_time); if (port_status != TIMED_OUT) { // IVR system answers first if (IVR_serv_time > 0.0) hold(exponential(IVR_serv_time)); // Check if IVR was successful (if not, need an operator) if (uniform01() <= IVR_success) Successful_calls++; else { wait_time = uniform(0.0, Max_hold); oper_status = timed_reserve(Operator, wait_time); if (oper_status != TIMED_OUT) { hold(exponential(Serv_time)); release(Operator); Successful_calls++; } else Operator_balks++; } deallocate(1, Port); } else Port_balks++; deallocate(1, Line); } else Busy_signals++; }