#include <limits.h>
#include <time.h>
#include <stdlib.h>
#include <math.h>
#include <vector>
#include <queue>
#include <functional>
#include "pqueue.h"
#include<iostream>
using namespace std;
class Event
{
enum { DIAL_IN = 1, HANGUP = 2 };
public:
Event( int name = 0, int tm = 0, int type = DIAL_IN )
: time( tm ), who( name ), what( type ) { }
bool operator> ( const Event & rhs ) const
{ return time > rhs.time; }
bool operator< ( const Event & rhs ) const
{ return time < rhs.time; }
friend class ModemSim;
private:
int who; int time; int what; };
typedef priority_queue<Event,vector<Event>,greater<Event> > PQ;
class ModemSim
{
public:
ModemSim( int modems, double avgLen, int callIntrvl );
void nextCall( int delta );
void runSim( int stoppingTime = INT_MAX );
private:
pqueue<Event> eventSet;
int freeModems; const double avgCallLen; const int freqOfCalls; int poisson( double expectedValue );
};
int ModemSim::poisson( double expectedValue )
{
double limit = -expectedValue;
double sum = log( static_cast<double>(rand())/
static_cast<double>(RAND_MAX));
int count;
for( count = 0; sum > limit; count++ )
sum += log(static_cast<double>(rand())
/static_cast<double>(RAND_MAX));
return count;
}
ModemSim::ModemSim( int modems, double avgLen, int callIntrvl )
: freeModems( modems ), avgCallLen( avgLen ),
freqOfCalls( callIntrvl )
{
nextCall( freqOfCalls ); }
void ModemSim::nextCall( int delta )
{
static int nextCallTime = 0;
static int userNum = 0;
eventSet.push( Event( userNum++, nextCallTime ) );
nextCallTime += poisson(static_cast<double>(delta));
}
void ModemSim::runSim( int stoppingTime )
{
static Event e;
int howLong;
while( !eventSet.empty( ) )
{
e = eventSet.top( );
eventSet.pop( );
if( e.time > stoppingTime )
break;
if( e.what == Event::HANGUP ) {
freeModems++;
cout << "User " << e.who << " hangs up at time "
<< e.time << endl;
}
else {
cout << "User " << e.who << " dials in at time "
<< e.time << " ";
if( freeModems > 0 )
{
freeModems--;
howLong = poisson( avgCallLen );
cout << "and connects for "
<< howLong << " minutes" << endl;
e.time += howLong;
e.what = Event::HANGUP;
eventSet.push( e );
cout << "Push(1) " << endl;
}
else
cout << "but gets busy signal" << endl;
nextCall( freqOfCalls );
}
}
}
int main( )
{
int numModems;
int totalTime;
double avgConnectTime;
int dialInFrequency;
cout << "Enter number of modems, length of simulation,\n"
<< " average connect time, how often calls occur: ";
cin >> numModems >> totalTime >>
avgConnectTime >> dialInFrequency;
ModemSim s( numModems, avgConnectTime, dialInFrequency );
s.runSim( totalTime );
return 0;
}