In: Computer Science
simulate the reception of a bank in C++ .
You will have customers requesting transactions (open account, deposit money, close account, withdraw money). You are required to simulate per the following parameters and rules: Customers coming at random times Each customer will require random amount of service time You may have 1-3 tellers based on the # of customers Once you have more than 4 customers waiting you need to get the 2nd teller Once you have more than 8 customers waiting you need to get the 3rd teller Once the line size gets smaller, you should remove the tellers in opposite order of their addition (the last one joining should be the first one leaving) The reception operates from 10:00 AM until 1:00 PM At the end of the day, you need to run the following reports: A list of customers coming along with the type of transactions they requested. This report should be sorted by: Last name of the customer Amount of money involved Time of arrival Average waiting time per customers Average number of customers waiting
# include <list.h>
# include <vector.h>
# include <stack.h>
# include <string>
//
//      class Customer
//              a single customer waiting in the bank teller line
class randomInteger {
        public:
                unsigned int operator () (unsigned int);
};
unsigned int randomInteger::operator () (unsigned int max)
{
                // rand return random integer
                // convert to unsigned to make positive
                // take remainder to put in range
        unsigned int rval = rand();
        return rval % max;
}
randomInteger randomizer;
class Customer {
public:
                // constructors
        Customer (int at) : arrivalTime(at), 
                        processTime(2 + randomizer(6)) {}
        Customer () : arrivalTime(0), processTime(0) { }
        
                // operations
        bool done    () { return --processTime < 0; }
        int  arrival () { return arrivalTime; }
        operator < (Customer & c)        // order by arrival time
                { return arrivalTime < c.arrivalTime; }
                
        operator == (Customer & c)  // no two customers are alike
                { return false; }
                
protected:
        unsigned int arrivalTime;
        unsigned int processTime;
};
//
//      class Teller
//              a teller servicing customers in a bank teller line
class Teller {
public:
        Teller() { free = true; }
        
        bool isFree()   // see if teller is free to work
        { 
                if (free) return true;
                if (customer.done())
                        free = true;
                  return free;
        }
        void addCustomer(Customer & c) // start servicing customer
        {
                customer = c;
                free = false;
        }
protected:
        bool free;
        Customer customer;
};
void main() {
        int numberOfTellers = 5;
        int numberOfMinutes = 60;
        double totalWait = 0;
        int numberOfCustomers = 0;
        vector < Teller > teller(numberOfTellers);
        queue < list< Customer > > line;
        
        for (int time = 0; time < numberOfMinutes; time++) {
                if (randomizer(10) < 9) {
                        Customer newCustomer(time);
                        line.push(newCustomer);
                        }
                for (int i = 0; i < numberOfTellers; i++) {
                        if (teller[i].isFree() & ! line.empty()) {
                                Customer frontCustomer = line.front();
                                numberOfCustomers++;
                                totalWait += (time - frontCustomer.arrival());
                                teller[i].addCustomer(frontCustomer);
                                line.pop();
                                }
                        }
                }
        cout << "average wait:" <<   (totalWait / numberOfCustomers) << endl;
}
Other references are:
http://web.eecs.utk.edu/~leparker/Courses/CS302-Fall06/Labs/Lab6/index.html
/* ---program3.cpp------------------------------------------------------------------
   A driver file for the Queue class which simulates a Queue at a bank. User 
   inputs a simulation time, transaction time, number of servers, and how often
   a new customer arrives. The driver then uses the Queue class to determine the
   average wait time of each customer, and how many customers remain in the line
   at the end of the simulation.
   Written by: Tyler Frye                       Tennessee Technological University
   Written for: CSC 2110                        Written on: March 06, 2010
   ---------------------------------------------------------------------------------*/
#include <iostream>
#include <iomanip>
using namespace std;
#include "Queue.h"
struct Teller_s {
        bool active;
        int time_At;
};
int main() {
        //Min/Max values for user input
        const int    MIN_SIM_TIME   = 0, MAX_SIM_TIME   = 10000,
                     MIN_TRANS_TIME = 0, MAX_TRANS_TIME = 100,
                                 MIN_NUM_SERV   = 0, MAX_NUM_SERV   = 10,
                                 MIN_ARRIV_TIME = 0, MAX_ARRIV_TIME = 100;
                                 
        char runAgain = 'Y'; //Set runAgain so the program runs
        int sim_Time, trans_Time, num_Serv, arriv_Time; //User input variables
        int i, c_Time; //Counters
        int customers, wait_Time; //Total customers and integer for customer waiting time
        while (runAgain != 'N') {
                i = 0; c_Time = 0;
                customers = 0; wait_Time = 0;
                
                Queue bankQ; //Create queue object
                
                cout << "\n------------------------------------------"
                         << "\n- Welcome to the Bank Simulation Program -"
                         << "\n------------------------------------------";
                
                //Menu information
                cout << "\n\nPlease input the following data(Time in minutes):\n";
                cout << "\nLength of the Simulation: ";
                cin >> sim_Time;
                while (sim_Time <= MIN_SIM_TIME || sim_Time > MAX_SIM_TIME) {
                        cout << "Invalid input. Please re-enter: ";
                        cin >> sim_Time;
                }
                cout << "Average Transaction Time: ";
                cin >> trans_Time;
                while (trans_Time <= MIN_TRANS_TIME || trans_Time > MAX_TRANS_TIME) {
                        cout << "Invalid input. Please re-enter: ";
                        cin >> trans_Time;
                }
                cout << "Average Number of Servers: ";
                cin >> num_Serv;
                while (num_Serv <= MIN_NUM_SERV || num_Serv > MAX_NUM_SERV) {
                        cout << "Invalid input. Please re-enter: ";
                        cin >> num_Serv;
                }
                cout << "Average Time Between Arrivals: ";
                cin >> arriv_Time;
                while (arriv_Time <= MIN_ARRIV_TIME || arriv_Time > MAX_ARRIV_TIME) {
                        cout << "Invalid input. Please re-enter: ";
                        cin >> arriv_Time;
                }
                
                //Dynamically allocate an array for the teller structure
                Teller_s * tellArray = new Teller_s[num_Serv];
                
                //Set all tellers to empty
                for (i = 0; i < num_Serv; i++) {
                        tellArray[i].active = false;
                        tellArray[i].time_At = trans_Time;
                }
                
                while (c_Time < sim_Time) { //Run until simulation time is reached
                        if (c_Time % arriv_Time == 0) { //Check if a customer should be enqueued
                                bankQ.enqueue();
                                customers++;
                        }
                        for (i = 0; i < num_Serv; i++) {
                                if (tellArray[i].active == false && bankQ.getSize() != 0) { //Dequeue if a teller is open
                                        bankQ.dequeue();
                                        tellArray[i].active = true;
                                        tellArray[i].time_At = trans_Time;                                              
                                }
                        }
                        
                        
                        
                        for (i = 0; i < num_Serv; i++) {
                                if (tellArray[i].active == true) {
                                        tellArray[i].time_At--;  //Decrement time spent at teller
                                }
                                if (tellArray[i].time_At == 0) {
                                        tellArray[i].active = false; //Set teller to open if time limit is reached
                                }
                        }
                        
                        wait_Time += bankQ.getSize(); //Set wait time to persons left in queue
                        c_Time++;
                }
                //Output user input data
                cout << "\n---------------"
                         << "\n- Data Output -"
                         << "\n---------------\n";
                         
                cout << setw(31) << left << "Simulation Time: ";
                cout << sim_Time << endl;
                
                cout << setw(31) << left << "Average Transaction Time: ";
                cout << trans_Time << endl;
                
                cout << setw(31) << left << "Average Number of Servers: ";
                cout << num_Serv << endl;
                
                cout << setw(31) << left << "Average Time Between Arrivals: ";
                cout << arriv_Time << endl << endl;
                
                //Output calculated data
                cout << "Average Total Wait Time: ";
                cout << fixed << setprecision(2)
                         << (float)wait_Time/customers;
                cout << "\nCustomers in line at end of simulation: "
                 << bankQ.getSize() << endl;
                
                //Ask to run again
                cout << "\nRun the program again? (y/n): ";
                cin >> runAgain;
                runAgain = (char)toupper(runAgain);
                while (runAgain != 'Y' && runAgain != 'N') {
                        cout << "Invalid Entry, please re-enter: ";
                        cin >> runAgain;
                        runAgain = (char)toupper(runAgain);
                }
                //Deallocate teller structure array
                delete [] tellArray;
        }       
        return 0;
}
/* ---Queue.h------------------------------------------------------------------
   A eader file for the Queue class which simulates a Queue in a bank
   environment.   
   Operations are:
   Queue(): Default constructor that sets first and last to null, and size to 0
   enqueue(): Adds a person into the queue and increments mySize
   dequeue(): Removes a person from the queue and decrements mySize
   front(): Returns the object in the front of the queue
   getSize(): Returns the current size of the queue
   ~Queue(): Deallocates the queue      
   Written by: Tyler Frye                       Tennessee Technological University
   Written for: CSC 2110                        Written on: March 06, 2010
   ---------------------------------------------------------------------------------*/
   
#ifndef QUEUE
#define QUEUE
#include <iostream>
using namespace std; 
typedef int ElementType;
class Queue {
        
        public:
                
                //Default constructor
                Queue();
                
                //Add to the back of the queue
                void enqueue();
                
                //Remove from the front of the queue
                void dequeue();
        
                //Returns the front of the queue
                ElementType front();
                
                //Return size of the queue
                int getSize();
                
                //Destructor
                ~Queue();
                
        private:
                
                class Node {
                
                        public:
                        
                                ElementType data;
                                Node *next;                              
                                Node(ElementType i) { // Node constructor
                                        data = i;
                                        next = NULL;
                                }
                }; //--- end of Node class
                
                typedef Node *NodePointer;
                
                Node *first;
                Node *last;
                int mySize;
                
}; //--- end of Queue class
#endif
/* ---Queue.cpp------------------------------------------------------------------
   An implementation file for the Queue class which simulates a Queue in a bank
   environment.   
   Operations are:
   Queue(): Default constructor that sets first and last to null, and size to 0
   enqueue(): Adds a person into the queue and increments mySize
   dequeue(): Removes a person from the queue and decrements mySize
   front(): Returns the object in the front of the queue
   getSize(): Returns the current size of the queue
   ~Queue(): Deallocates the queue      
   Written by: Tyler Frye                       Tennessee Technological University
   Written for: CSC 2110                        Written on: March 06, 2010
   ---------------------------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include "Queue.h"
Queue::Queue() {
        mySize = 0;
        first = NULL;
        last = NULL;    
}
void Queue::enqueue() {
        NodePointer nPtr = new Node(1);
        NodePointer predPtr = first;
        
        if (first == NULL) { //Insert if queue is empty
                nPtr->next = first;
                first = nPtr;
        } else { //Insert into the queue at the end
                while (predPtr->next) {
                        predPtr = predPtr->next;
                }
                nPtr->next = predPtr->next;
        }
        mySize++;
        last = nPtr; //Set last to new pointer
}
void Queue::dequeue() {
        if (first) {
                NodePointer dPtr = first;
                first = first->next; //Set first to the second node in the list
                delete dPtr; //Delete the node that has been dequeued
        }
        mySize--;
}
ElementType Queue::front() {
        if (first) {
                NodePointer ptr = first;
                return ptr->data;
        }
}
int Queue::getSize() {
        return mySize;
}
Queue::~Queue() {
        if (first) {
                //Deallocate all nodes in queue
                NodePointer current = first;
                NodePointer temp = first;
                
                temp = current->next;
                delete current;
                current = temp;
        }
}