Skip to content

Simulation

There are 2 types of simulation models. 1. Time-based simulation. 2. Event-based simulation.

In time based simulation, we maintain a clock for things (or events) to happen.
In event based simulation, we maintain a list of events along with their computed times in increasing order. We do not wait for the clock to tick till the next event.

Priority Queue

a queue where the de-queue operation does not depends on the FIFO but rather depends on the events with their time required for completion, is called priority-queue.

Imagine a file with following data:

00 30 10
00 35 05
00 40 08
00 45 02
00 50 05
00 55 12
01 00 13
01 01 09

Where the first column represents hours, 2nd represents minutes and 3rd represents time required for transaction. (Example of 4 queues in front of 4 tellers in a bank).

#include <iostream>
#include <string>
#include <strstream.h>

#include "Customer.cpp"
#include "Queue.h"
#include "PriorityQueue.cpp"
#include "Event.cpp"

Queue q[4];       // teller queues
PriorityQueue pq; //eventList;
int totalTime;
int count = 0;
int customerNo = 0;

int main (int argc, char *argv[]) {
    Customer* c;
    Event* nextEvent;
    // open customer arrival file
    ifstream data("customer.dat", ios::in);
    // initialize with the first arriving customer.
    ReadNewCustomer(data);

    while( pq.length() > 0 ) {

        nextEvent = pq.remove();
        c = nextEvent->getCustomer();

        if( c->getStatus() == -1 ){  // arrival event
            int arrTime = nextEvent->getEventTime();
            int duration = c->getTransactionDuration();
            int customerNo = c->getCustomerNumber();
            processArrival(data, customerNo, arrTime, duration , nextEvent);
        }

        else{  // departure event
            int qindex = c->getStatus();
            int departTime = nextEvent->getEventTime();
            processDeparture(qindex, departTime, nextEvent);
        }
    }
}

Some of the functions used:

void readNewCustomer(ifstream& data) {
    int hour,min,duration;

    if (data >> hour >> min >> duration) {
        customerNo++;
        Customer* c = new Customer(customerNo, hour*60+min, duration);
        c->setStatus( -1 ); // new arrival
        Event* e = new Event(c, hour*60+min );
        pq.insert( e ); // insert the arrival event
    }

    else {
        data.close(); // close customer file
    }
}
int processArrival(ifstream &data, int customerNo, int arrTime, int duration, Event* event) {
    int i, small, j = 0;
    // find smallest teller queue
    small = q[0].length();
    for(i=1; i < 4; i++ )
        if( q[i].length() < small )
            small = q[i].length(); j = i;

    // put arriving customer in smallest queue
    Customer* c = new Customer(customerNo, arrTime, duration );
    c->setStatus(j);  // remember which queue the customer goes in
    q[j].enqueue(c);

    // check if this is the only customer in the.
    // queue. If so, the customer must be marked for
    // departure by placing him on the event queue.
    if( q[j].length() == 1 ) {
        c->setDepartureTime( arrTime+duration);
        Event* e = new Event(c, arrTime+duration );
        pq.insert(e);
    }

    // get another customer from the input
    readNewCustomer(data);
}
int processDeparture(int qindex, int departTime, Event* event) {
    Customer* cinq = q[qindex].dequeue();
    int waitTime = departTime - cinq->getArrivalTime();
    totalTime = totalTime + waitTime;
    count = count + 1;

    // if there are any more customers on the queue, mark the
    // next customer at the head of the queue for departure
    // and place him on the eventList.
    if( q[qindex].length() > 0 ) {
        cinq = q[qindex].front();
        int etime = departTime + cinq->getTransactionDuration();
        Event* e = new Event(cinq, etime);
        pq.insert( e );
    }
}