```
#include <iostream.h>
#include <stdlib.h>
#include <math.h>
#include <fstream.h>
#include <conio.h>
#define maxSource 10 //refer to maximum source that are 10 sources
#define maxEvent 2 //refer to number of events that are only 2, 0 for arrival, and 1 for departure
#define maxQSize 20 //maximum queue size is set to 20
#define serviceTime 0.122 //set the service time to 0.122
#define maxDelay 0.01 //set the maximum delay to 0.01
/*random early detection*/
#define wq 0.002
#define minth 5
#define maxth 15
#define maxp 0.02
#define MAX_BANDWIDTH 512000
#define avg_pktsize 500
double ev_time[maxSource][maxEvent]; //the main event time
double smallestEvent; //holds the smallest eventime. Used by scheduler() and Clock()
double simClock;
double last_check;
double iat;
double totalDelay;
int load=0;
double arrivalTimeQ[maxQSize+1]; //holds the arrival time of customers that enter the queue (maxSource+1 because the index of 0 is not used)
int eventType; //holds the event type, it is either 0 or 1. Used by scheduler() and selectEvent()
int packetNum; //holds the customer number to be entered to the system. Use by the scheduler() and the arrival() or departure()
int serviceCounter = 0; //if the service counter is idle, then 0
int packetNumQ[maxQSize+1]; //holds the customer number that enters into the queue (maxSource+1 because the index of 0 is not used)
int currentQSize=0; //holds the current queue size. Used by the arrival() and departure()
double numPacketArrived; //holds the number of customers arrived in the system
double numPacketDeparted; //holds the number of customers completed an entire cycle in the bank
double totalCustLost; //holds the number of customers lost when the Q is full
void calculateavg1();
void calculateavg2();
//double calculateavg1(double avg);
//double calculateavg2(double avg);
/*random early detection*/
double avg=0;
int m;
double idletime_;
double pa;
double pb;
int count=0;
double ptc=0;
ofstream fout("output.txt", ios::app);
void IAT()
{
double rand_size = 0.5 * pow(2.0,8.0 * sizeof(int));
double x;
while(1)
{
x = (float) rand();
if (x!=0.0)
break;
}
iat = - (log (x/rand_size))/load;
}
//initialize the values of variables
void init()
{
totalDelay = 0.0;
simClock = 0.0;
numPacketArrived = 0;
numPacketDeparted = 0;
totalCustLost = 0;
currentQSize = 0;
load += 10;
IAT();
serviceCounter = 0;
}
//generate events and create the starting arrival time of the simiulation
void eventList()
{
for (int i=0; i<maxSource; i++)
{
for (int j=0; j<maxEvent; j++)
{
ev_time[i][j] =0.0; //this is to return a value between 0.00 till 9.99
if (j==1) //j==1 means the departure time slot coz 0 is for arrival
ev_time[i][j] = 1.0e+30; //departure time set to infinity
//fout<< ev_time[i][j] << "\t";
}
// fout<< endl;
}
}
//find the smallest event time to be placed into the system
void scheduler()
{
// fout<< "Scheduler" << "\t";
smallestEvent = 1.0e+30;
for (int i=0; i<maxSource; i++)
{
for(int j=0; j<maxEvent; j++)
{
if(ev_time[i][j] < smallestEvent)
{
smallestEvent = ev_time[i][j]; //records the smallest time in the sources
eventType = j; //records the event type, either 0 or 1
packetNum = i; //records the customer number
}
}
}
}
//assign the smallest event time to a clock
void Clock()
{
simClock = smallestEvent; //the clock ticks for the updates
//fout<< simClock << "\t" ;
}
//moves the customers in Q to the front of the Q
void swap()
{
for (int i=1; i<maxQSize; i++)
{
arrivalTimeQ[i] = arrivalTimeQ[i+1];
packetNumQ[i] = packetNumQ[i+1];
}
}
void idle()
{
if(currentQSize!=0)
{
idletime_=simClock;
}
else
{
idletime_=0.0;
}
}
void avg1()
{
if(avg<minth)
{
count=-1;
++numPacketArrived;
currentQSize++;
}
else if (avg>=minth&&avg<maxth)
{
count=count+1;
//calculate pa
pb=maxp*(avg-minth)/(maxth-minth);
pa=pb/((1-count)*pb);
if(pa<maxp)
{
++numPacketArrived;
currentQSize++;
}
else
{
totalCustLost++;
currentQSize--;
}
}
}
void calculateavg1()
{
avg=((1-wq)*avg)+(wq*currentQSize);
fout<<"avg"<<avg<<endl;
avg1();
}
void calculateavg2()
{
ptc=MAX_BANDWIDTH/(8.0*avg_pktsize);
m=int(ptc*(simClock-idletime_));
idle();
//m=int(idletime_/(avg_pktsize/MAX_BANDWIDTH));
avg=pow(1-wq,m)*avg;
avg1();
}
//arrival function
void arrival()
{
++numPacketArrived;
IAT();
ev_time[packetNum][0] = simClock + iat; //schedule the next customer
if (serviceCounter == 0) //service counter idle
{
serviceCounter = 1; //make the service counter busy
ev_time[packetNum][1] = simClock + serviceTime; //schedule the departure time
}
else if (serviceCounter == 1) //service counter busy
{
if (currentQSize < maxQSize)
{
calculateavg1();
currentQSize++; //increase the Q size
//the queue starts at index of 1, not 0
arrivalTimeQ[currentQSize] = simClock; //records the arrival time of customer into the Q
packetNumQ[currentQSize] = packetNum; //records the customer number in the Q
}
else if (currentQSize==0)
{
calculateavg2();
}
else
{
++totalCustLost;
// fout<< "Customer " << packetNum << " is lost!!" << endl;
}
}
}
//departure function
void departure()
{
double delay; //holds the delay of the customer temporarily
int cid; //holds the customer number from the Q temporarily
++numPacketDeparted; //increments the total number of customers departed after being served
if (currentQSize == 0) //the Q is empty
{
serviceCounter = 0; //make the service counter free
ev_time[packetNum][1] = 1.0e+30; //change the departure time to infinity as the customer has left
}
else if (currentQSize > 0)
{
--currentQSize; //reduce the Q size as the customer moved out of the Q
ev_time[packetNum][1] = 1.0e+30; //change the departure time to infinity as the customer has left
delay = simClock - arrivalTimeQ[1]; //calculate the delay for that 1st customer in the Q
totalDelay += delay; //calculate the total delay of the system
cid = packetNumQ[1]; //extract the 1st customer number from the Q
ev_time[cid][1] = simClock + serviceTime; //schedule the departure time for the customer from the Q
swap();
//moves the customers to the front of the Q
}
}
void selectEvent()
{
switch (eventType)
{
case 0 : // fout<< "Arrival" << endl;
arrival();
break;
case 1 : // fout<< "Depart" << endl;
departure();
break;
}
}
void result()
{
cout<< "TotalDelay \t\t" << totalDelay << endl;
cout<< "SimClock \t\t" << simClock << endl;
cout<< "TotalCustLost \t\t" << totalCustLost << endl;
cout<< "numPacketArrived \t" << numPacketArrived << endl;
cout<< "numPacketDeparted \t" << numPacketDeparted << endl;
cout<< "CurrentQSize \t\t" << currentQSize << endl; //display currently how many person in Q
cout<< "ServiceCounter \t\t" << serviceCounter << endl << endl << endl;
cout<< "Customer Loss Ratio : " << (double) totalCustLost / numPacketArrived << endl;
cout<< "Average Delay : " << (double) totalDelay / numPacketDeparted << endl;
cout<< "pa:"<<pa<<endl;
fout<< load << " " << totalDelay/numPacketDeparted <<" "<<totalCustLost/numPacketArrived <<endl;
//cout<<"count"<<" "<<count<<endl;
cout<<"avg"<< " "<<avg<<endl;
//cout<<"avg "<<avg<<endl;
//fout<<"pa "<<pa<<endl;
}
//function that clears the arrival events by setting them to infinity
/*void clearArrival()
{
for (int i=0; i<maxSource; i++)
{
for (int j=0; j<maxEvent; j++)
{
if (j==0) //j==0 means the arrival
ev_time[i][j] = 1.0e+30; //arrival time is infinity
}
}
}
*/
void main()
{
// clrscr();
load = 0;
for (int i=0; i<10; i++)
{
init();
eventList();
while (numPacketDeparted <= 5000)
{
//once the system achieved this target num of customer, it will clear the arrival event
//and continue clearing the bank, meanning only departure
scheduler();
Clock();
selectEvent();
}
result();
}//e-for
} //e=main
```