Demo entry 6625826

hee

   

Submitted by anonymous on Jun 22, 2017 at 09:36
Language: C++. Code size: 10.2 kB.

#include <iostream>
#include <random>
#include <vector>
#include <queue>
#include <cstdlib>
#include <ctime>
#include <cmath>

using namespace std;
class event {
public:
    event(int t) : time(t)
    {}
    virtual void processEvent() = 0;
    const int time;
};

class carrierSenseEvent : public event {
public:
    carrierSenseEvent (int t, int k, int n, int c) : event(t), k(k), node(n), created(c) { }
    virtual void processEvent();
    // Data fields.
    int k = 0;
    int node;
    int created = 0;
};

class carrierResenseEvent : public event {
public:
    carrierResenseEvent (int t, int k, int n, int c) : event(t), k(k), node(n), created(c) { }
    virtual void processEvent();
    // Data fields.
    int k = 0;
    int node;
    int created = 0;
    bool isCollision = false;
};

class carrierBackoffsenseEvent : public event {
public:
    carrierBackoffsenseEvent (int t, int k, int n, int c) : event(t), k(k), node(n), created(c) { }
    virtual void processEvent();
    // Data fields.
    int k = 0;
    int node;
    int created = 0;
};

class packetBackoffEvent : public event {
public:
    packetBackoffEvent (int t, int k, int b, int n, int c) : event(t), k(k), backoff(b), node(n), created(c) { }
    virtual void processEvent();
    // Data fields.
    int k = 0;
    int node;
    int backoff = 0;
    int created = 0;
    bool isCollision = false;
};

class packetTransmitEvent : public event {
public:
    packetTransmitEvent (int t, int n, int c) : event(t), node(n), created(c) { }
    virtual void processEvent();
    // Data fields.
    int node;
    int created = 0;
};

class packetSuccessEvent : public event {
public:
    packetSuccessEvent (int t, int n, int c) : event(t), node(n), created(c) { }
    virtual void processEvent();
    // Data fields.
    int node;
    int created = 0;
};

struct eventComparator {
    bool operator() (event* left, event* right) const {
        if(left->time == right->time) {
            packetSuccessEvent* psleft = dynamic_cast<packetSuccessEvent *>(left);
            packetSuccessEvent* psright = dynamic_cast<packetSuccessEvent *>(right);
            if(psright && !psleft) return true;
            else if(!psright && psleft) return false;
            packetBackoffEvent* pbleft = dynamic_cast<packetBackoffEvent *>(left);
            packetBackoffEvent* pbright = dynamic_cast<packetBackoffEvent *>(right);
            if(pbleft && pbright) {
//                cout << "here" << endl;
                return pbleft->backoff > pbright->backoff;
            }
            carrierResenseEvent* crleft = dynamic_cast<carrierResenseEvent *>(left);
            carrierResenseEvent* crright = dynamic_cast<carrierResenseEvent *>(right);
            if(crleft && !crright) return true;
            else if(!crleft && crright) return false;
        }
        return left->time > right->time;
    }
};

class simulation {
public:
    simulation () : time(0), eventQueue()
    {}
    void run();
    void scheduleEvent(event* newEvent) {
        eventQueue.push(newEvent);
    }
    int time;
protected:
    priority_queue<event*, vector<event*, allocator<event*> >, eventComparator> eventQueue;
};

void simulation::run() {
    while(!eventQueue.empty() && eventQueue.top()->time < 1000000) {
        event* nextEvent = eventQueue.top();
        eventQueue.pop();
        time = nextEvent->time;
        nextEvent->processEvent();
        delete nextEvent;
    }
}

class CSMACAsimulation : public simulation {
public:
    CSMACAsimulation() : simulation() { }
    bool collisionCheck (int t);
    int randomNumberGenerate ();
    // Data fields.
    int nextIdle = 0;
    bool isBusy = false;
    int collisionCounter = 0;
    int transmissionCounter = 0;
    int packetDelay = 0;
    default_random_engine* generator;
    poisson_distribution<int>* distribution;
} theSimulation;

int transmissionTime = 819;
int slot = 20;
int rambda;
int numberOfnodes;
int DIFS = 50;
int SIFS = 10;

bool CSMACAsimulation::collisionCheck(const int t) {
    if(eventQueue.empty()) return false;
    if(isBusy) return false;
    event* nextEvent = eventQueue.top();
    carrierResenseEvent* carrierResenseNextEvent = dynamic_cast<carrierResenseEvent *>(nextEvent);
    packetBackoffEvent* packetBackoffNextEvent = dynamic_cast<packetBackoffEvent *>(nextEvent);
    if (carrierResenseNextEvent && carrierResenseNextEvent->time == t) {
        carrierResenseNextEvent->isCollision = true;
        return true;
    } else if (packetBackoffNextEvent && packetBackoffNextEvent->time == t && packetBackoffNextEvent->backoff == 0) {
        packetBackoffNextEvent->isCollision = true;
        return true;
    } else
        return false;
}

int CSMACAsimulation::randomNumberGenerate() {
    return (*distribution)(*generator);
}

void carrierSenseEvent::processEvent() {
   cout << "[ " << node << " ] carrier sense event with backoff " << k << endl << "time: " << time << endl;
    if (!theSimulation.isBusy) {
        theSimulation.scheduleEvent(new carrierResenseEvent(time + DIFS, k, node, time));
        return;
    } else {
        theSimulation.scheduleEvent(new carrierBackoffsenseEvent(theSimulation.nextIdle + DIFS, k, node, time));
        return;
    }
}

void carrierResenseEvent::processEvent() {
   cout << "[ " << node << " ] carrier resense event with backoff " << k << endl << "time: " << time << endl;
    if (theSimulation.collisionCheck(time)) {
        isCollision = true;
        --theSimulation.collisionCounter;
    }
    if (isCollision) {
        ++theSimulation.collisionCounter;
        if (k > 15) {
            int poisson = theSimulation.randomNumberGenerate();
            theSimulation.scheduleEvent(new carrierSenseEvent(time + poisson, 0, node, time + poisson));
            return;
        } else {
            int backoff = rand() % (int)(pow(2.0, (double) (k > 10 ? 10 : k)) + 0.5) + 1;
            theSimulation.scheduleEvent(new carrierSenseEvent(time + backoff * slot, k + 1, node, created));
            return;
        }
    }
    if (!theSimulation.isBusy) {
        theSimulation.scheduleEvent(new packetTransmitEvent(time, node, created));
        return;
    } else {
        theSimulation.scheduleEvent(new carrierBackoffsenseEvent(theSimulation.nextIdle + DIFS, k, node, created));
        return;
    }
}

void carrierBackoffsenseEvent::processEvent() {
   cout << "[ " << node << " ] carrier backoffsense event with backoff " << k << endl << "time: " << time << endl;
    if (theSimulation.isBusy) {
        theSimulation.scheduleEvent(new carrierBackoffsenseEvent(theSimulation.nextIdle + DIFS, k, node, created));
        return;
    } else {
        int backoff = rand() % (int)(pow(2.0, (double) (k > 10 ? 10 : k)) + 0.5) + 1;
        theSimulation.scheduleEvent(new packetBackoffEvent(time, k, backoff, node, created));
        return;
    }
}

void packetTransmitEvent::processEvent() {
   cout << "[ " << node << " ] packet transmit event" << " created at " << created << endl << "time: " << time << endl;
    theSimulation.isBusy = true;
    theSimulation.scheduleEvent(new packetSuccessEvent(time + transmissionTime * 2 + SIFS, node, created));
    theSimulation.nextIdle = time + transmissionTime  * 2 + SIFS;
    return;
}

void packetSuccessEvent::processEvent() {
   cout << "[ " << node << " ] packet success event" << " created at " << created << endl << "time: " << time << endl;
    theSimulation.transmissionCounter += 2;
    theSimulation.packetDelay += time - created;
    theSimulation.isBusy = false;
    int poisson = theSimulation.randomNumberGenerate();
    theSimulation.scheduleEvent(new carrierSenseEvent(time + poisson, 0, node, time + poisson));
    return;
}

void packetBackoffEvent::processEvent() {
   cout << "[ " << node << " ] packet backoff event with backoff " << backoff << endl << "time: " << time << endl;
    if (theSimulation.isBusy) {
        theSimulation.scheduleEvent(new packetBackoffEvent(theSimulation.nextIdle, k, backoff, node, created));
        return;
    } else {
        if (backoff == 0) {
            if (theSimulation.collisionCheck(time)) {
                isCollision = true;
                --theSimulation.collisionCounter;
            }
            if (isCollision) {
                ++theSimulation.collisionCounter;
                if (k > 15) {
                    int poisson = theSimulation.randomNumberGenerate();
                    theSimulation.scheduleEvent(new carrierSenseEvent(time + poisson, 0, node, time + poisson));
                    return;
                } else {
                    int backoff = rand() % (int)(pow(2.0, (double) (k > 10 ? 10 : k)) + 0.5) + 1;
                    theSimulation.scheduleEvent(new carrierSenseEvent(time + backoff * slot, k + 1, node, created));
                    return;
                }
            }
            theSimulation.scheduleEvent(new packetTransmitEvent(time, node, created));
            return;
        } else {
            theSimulation.scheduleEvent(new packetBackoffEvent(time + slot, k, backoff - 1, node, created));
            return;
        }
    }
}

int main(int argc, char* argv[]) {
    numberOfnodes = stoi(argv[1]);
    rambda = stoi(argv[2]);
    srand(time(NULL));
    default_random_engine generator(time(NULL));
    poisson_distribution<int> distribution(rambda);
    theSimulation.distribution = &distribution;
    theSimulation.generator = &generator;
    for(int i = 0; i < numberOfnodes; ++i) {
        int poisson = theSimulation.randomNumberGenerate();
        theSimulation.scheduleEvent(new carrierSenseEvent(poisson, 0, i, poisson));
    }
    theSimulation.run();
    cout << endl
        << "The # of Collision: " << theSimulation.collisionCounter << endl
        << "The # of Transmission ( = Throughput): "
         << theSimulation.transmissionCounter << endl
        << "Packet Delay: " << theSimulation.packetDelay << endl
        << "Mean packet Delay: "
         <<  (double)theSimulation.packetDelay / theSimulation.transmissionCounter << endl
        << "Transmission collision probability: "
         << (double)theSimulation.collisionCounter / theSimulation.transmissionCounter << endl;
    return 0;
}

This snippet took 0.02 seconds to highlight.

Back to the Entry List or Home.

Delete this entry (admin only).