int main()
{
  bool    done             = false;
  double  EN               = 0.0;     // For calculating E[N]
  double  Util             = 0.0;
  Event*  CurrentEvent;

  //Get system configuration inputs from user
  getUserInputs();

  countInfo.terminalPool = configInfo.numTerminals;

  //this will initialize the queuing system
  initializeQSystem(configInfo.numTerminals);

  /*
   * This while loop represents the finite population system where
   * customer arrive (from the event list in our case),
   * get accepted if the system has capacity, get served
   * by the next available server and then depart
   */
  while (!done)
  {
    CurrentEvent = Elist.get();               // Get next Event from list
    double prev = clock;                      // Store old clock value
    clock=CurrentEvent->time;                 // Update system clock

    switch (CurrentEvent->type)
    {
      case ARR:
        countInfo.NArr++;
        EN += countInfo.NSys*(clock-prev);

        if(countInfo.NSys<configInfo.numCPU)
          Util += countInfo.NSys*(clock-prev);
        else
          Util += configInfo.numCPU*(clock-prev);

        if(countInfo.serverPool<configInfo.numCPU)
        {
          //Server is idle, accept the element in the system and depart it
          countInfo.serverPool++;
          countInfo.NSys++;
          Elist.insert(clock+exp_rv(configInfo.serviceRate),DEP);
        }
        else if((countInfo.serverPool==configInfo.numCPU) &&
                (countInfo.NQueue<configInfo.queueSize))
        {
          //All servers are occupied, accept the element and queue it
          countInfo.NSys++;
          countInfo.NQueue++;
        }
        else if((countInfo.serverPool==configInfo.numCPU) &&
                (countInfo.NQueue == configInfo.queueSize))
        {
          //system is full to its capacity. Block the customer and free a terminal
          countInfo.NBlocked++;
          countInfo.terminalPool++;
          generateArrEvent(configInfo.numTerminals);
        }
        break;
      case DEP:
        EN += countInfo.NSys*(clock-prev);

        if(countInfo.NSys<configInfo.numCPU)
          Util += countInfo.NSys*(clock-prev);
        else
          Util += configInfo.numCPU*(clock-prev);

        if(countInfo.NSys)
        {
          countInfo.NSys--;
          countInfo.serverPool--;
          countInfo.terminalPool++;
          countInfo.NDep++;
          if ((countInfo.serverPool < configInfo.numCPU) && (countInfo.NQueue>0))
          {
            //If a server is idle and customer is waiting in queue then generate dep
            countInfo.serverPool++;
            countInfo.NQueue--;
            Elist.insert(clock+exp_rv(configInfo.serviceRate),DEP);
          }
        }
        //triger new arrival. If a terminal is free then it will generate arr
        generateArrEvent(configInfo.numTerminals);
        break;
    }
    delete CurrentEvent;
    if (countInfo.NDep > 100000)
      done=true;        // End condition
  }
  cout<<endl<<"****Statistical Output with lambda="<<configInfo.arrivalRate<<"****"<<endl;
  cout <<"Expected number of customers (simulation)= " << EN/clock << endl;
  cout<<"Expected time spent in the system= "<<EN/100000<<endl;
  cout<<"P(Blocking)= "<<(double)countInfo.NBlocked/countInfo.NArr<<endl;
  cout<<"Utilization= "<<(double)Util/(clock*configInfo.numCPU)<<endl;
}
Esempio n. 2
0
int main()
{
    using namespace std;
    EventList Elist;                // Create event list
    enum {ARR,DEP1,DEP2,DEP3,TRANSFER11,TRANSFER13,TRANSFER23,TRANSFER32,TDEP1,TDEP2,TDEP3};                 // Define the event types
    enum{Q1,Q2,Q3};
    
    double lambda=1;            // Arrival rate
    double mu1 = 6.0;
    double mu2 = 25.0;
    double mu3 = 30.0;
    
        exp_rv(lambda);
    double rs1 = (double)1/4;
    double rs2 = (double)3/4;
    double r11 = (double)1/2,r13 = (double)1/2,r3d = (double)2/5,r32 =(double)3/5;
    
    int N = 0;                      // Number of customers in system
    int Ndep = 0;                   // Number of departures from system
    
                      // End condition satisfied?
    
    Event* CurrentEvent;
    
    
    for(lambda = 1; lambda <= 10 ; lambda++ )
    {
        
        int n1 = 0;
        int n2=0;
        int n3=0;
        int tn1 = 0;
        int tn2=0;
        int tn3=0;
        
        int qe1=0,qe2=0,qe3=0; //to keep total entering each queue. for throughput calculation
        double util1=0,util2=0,util3=0, rho1=0, rho2=0, rho3=0;
        
        if(randomGenerator() <= rs1)
            Elist.insert(exp_rv(lambda),ARR,Q1);
        else
            Elist.insert(exp_rv(lambda),ARR,Q2);

        double clock = 0.0;             // System clock
        Ndep = 0;
        double EN1 = 0.0, EN2 = 0.0, EN3 = 0.0;
        int done = 0;
        while (!done)
        {
            CurrentEvent = Elist.get();
            double prev = clock;
            clock=CurrentEvent->time;
            EN1 += (double)((n1+tn1)*(clock-prev));
            EN2 += (double)((n2+tn2)*(clock-prev));
            EN3 += (double)((n3+tn3)*(clock-prev));
            
            if((n1+tn1)>0)
            util1+=(clock-prev);
            if((n2+tn2)>0)
            util2+=(clock-prev);
            if((n3+tn3)>0)
            util3+=(clock-prev);
            
            
            switch (CurrentEvent->type)
            {
            case ARR:
                if(CurrentEvent->queue == 0)
                {
                    n1++;
                    qe1++;
                    //generate next arrival
                    if(randomGenerator() <= rs1)
                        Elist.insert(clock+exp_rv(lambda),ARR, Q1);
                    else
                        Elist.insert(clock+exp_rv(lambda),ARR, Q2);
                
                    if (n1==1)
                    {
                        Elist.insert(clock+exp_rv(mu1),DEP1, Q1);
                    }
                }
                else if(CurrentEvent->queue == 1)
                {
                    n2++;
                    qe2++;
                    //generate next arrival
                    if(randomGenerator() <= rs1)
                        Elist.insert(clock+exp_rv(lambda),ARR, Q1);
                    else
                        Elist.insert(clock+exp_rv(lambda),ARR, Q2);
                    
                    if (n2==1)
                    {
                        Elist.insert(clock+exp_rv(mu2),DEP2, Q2);
                    }
                }
                
                break;
                
                case DEP2:
                n2--;
                if (n2 > 0)
                {
                    Elist.insert(clock+exp_rv(mu2),DEP2,Q2);
                }
                
                Elist.insert(clock+exp_rv(mu2),TRANSFER23, Q3);
                break;
                
                
                case TRANSFER11:
                    tn1++;
                    qe1++;
                    if(tn1>0)
                    {
                        //Generate TDEP for this transfer event
                        Elist.insert(clock+exp_rv(mu1), TDEP1, Q1);
                    }
                    break;
                
                    
                case TDEP1:
                    tn1--;
                    if(randomGenerator()<=r11)
                    {
                    //Its going back to the same queue. Don't generate new arrival event. generate transfer event
                        Elist.insert(clock+exp_rv(mu1),TRANSFER11,Q1);
                    }
                    else
                    {
                        Elist.insert(clock+exp_rv(mu1),TRANSFER13,Q3);
                    
                    }
                break;
                
                    
                case TRANSFER13:
                    tn3++;
                    qe3++;
                    if(tn3>0)
                    {
                        //Generate TDEP for this transfer event
                        Elist.insert(clock+exp_rv(mu3), TDEP3, Q3);
                    }
                    break;
                    
                case TDEP3:
                    tn3--;
                    if(randomGenerator()<=r3d)
                    {
                        //Exits the system
                        Ndep++;
                    }
                    else
                    {
                        Elist.insert(clock+exp_rv(mu3),TRANSFER32,Q2);
                    }
                    break;
                
                case TRANSFER23:
                    tn3++;
                    qe3++;
                    if(tn3>0)
                    {
                        //Generate TDEP for this transfer event
                        Elist.insert(clock+exp_rv(mu3), TDEP3, Q3);
                    }
                    break;
                    
                    
                case TRANSFER32:
                    tn2++;
                    qe2++;
                    if(tn2>0)
                    {
                        //Generate TDEP for this transfer event
                        Elist.insert(clock+exp_rv(mu2), TDEP2, Q2);
                    }
                    break;
                    
                case TDEP2:
                    tn2--;
                    Elist.insert(clock+exp_rv(mu2),TRANSFER23, Q3);
                    break;
                
                case DEP1:
                    n1--;
                    if (n1 > 0)
                    {
                        Elist.insert(clock+exp_rv(mu1),DEP1,Q1);
                    }
                
                    
                    if(randomGenerator()<=r11)
                    {
                    //Its going back to the same queue. Don't generate new arrival event. generate transfer event
                        Elist.insert(clock+exp_rv(mu1),TRANSFER11,Q1);
                    
                    }
                    else
                    {
                        Elist.insert(clock+exp_rv(mu1),TRANSFER13,Q3);
                    }
                    break;
                
                }
            
            EN1=(double)(((qe1/clock)/mu1)/(1-((qe1/clock)/mu1)))*clock; EN2 = (double)(((qe2/clock)/mu2)/(1-((qe2/clock)/mu2)))*clock; EN3=(double)(((qe3/clock)/mu3)/(1-((qe3/clock)/mu3)))*clock;
            //cout<<CurrentEvent->type<<endl;
            //cout<<"N1 : "<<n1+tn1<<"    N2 : "<<n2+tn2<<"    N3 : "<<n3+tn3<<"    Ndep : "<<Ndep<<endl;
            
        delete CurrentEvent;
        if (Ndep > 500000) done=1;        // End condition
    }
        
        
        
        /*Printing Output for each iteration */
        
        
        
        rho1=(double)(qe1/clock)/mu1;
        rho2=(double)(qe2/clock)/mu2;
        rho3=(double)(qe3/clock)/mu3;
        cout<<"Lambda "<<lambda<<endl;
        cout<<"TP1 : "<<qe1/clock<<"    TP2 : "<<qe2/clock<<"    TP3 : "<<qe3/clock<<endl;
        cout<<"Util1 : "<<(rho1)<<"    Util2 : "<<rho2<<"    Util3 : "<<rho3<<endl;
        cout<<"EN1 : "<<EN1/clock<<"    EN2 : "<<EN2/clock<<"    EN3 : "<<EN3/clock<<endl;
        cout<<"E[T1] : "<<(double)(EN1/qe1)<<"    E[T2] : "<<(double)(EN2/qe2)<<"    E[T3] : "<<(double)(EN3/qe3)<<endl;
        
        cout<<endl<<endl;
        
        Elist.clear();
        
}
    
}
int main()
{
    using namespace std;
    EventList Elist;
    enum{ARR,DEP1,DEP2,DEP3};

    double rs1,rs2,r11,r13,r3d,r32,mu1,mu2,mu3;
    double clock;                 // System clock
    double EN1;
    double EN2;
    double EN3;
    int N1;                      // Number of customers in queue1
    int N2;
    int N3;
    int Ndep1;                   // Number of departures from queue1
    int Ndep2;
    int Ndep3;
    int Ndep_system;                //# of departures from system
    double U1;
    double U2;
    double U3;
	double lambda;


    cout << "Please input a lambda value(1 to 10): "<< endl;
	cin >> lambda;
    cout << "Please input the rs1 : " << endl;
	cin >> rs1;
	cout << "Please input the rs2 : " << endl;
	cin >> rs2;
	cout << "Please input the r11 : " << endl;
	cin >> r11;
	cout << "Please input the r13 : " << endl;
	cin >> r13;
	cout << "Please input the r3d : " << endl;
	cin >> r3d;
	cout << "Please input the r32 : " << endl;
	cin >> r32;
	cout << "Please input the mu1 : " << endl;
	cin >> mu1;
	cout << "Please input the mu2 : " << endl;
	cin >> mu2;
	cout << "Please input the mu3 : " << endl;
	cin >> mu3;

    int done = 0;                   // End condition satisfied?
    int i;

   
		clock = 0.0;
		N1 = 0;
		N2 = 0;
		N3 = 0;
		EN1 = 0.0;
        EN2 = 0.0;
        EN3 = 0.0;
		Ndep1 = 0;
		Ndep2 = 0;
		Ndep3 = 0;
		Ndep_system = 0;
		U1 = 0.0;
		U2 = 0.0;
		U3 = 0.0;        

		Event* CurrentEvent;
		
		Elist.insert(exp_rv(lambda),ARR);

		while (!done)
		{

		    CurrentEvent = Elist.get();               // Get next Event from list
            double prev = clock;                      // Store old clock value
            clock = CurrentEvent->time;                 // Update system clock
            EN1 += N1*(clock-prev);
            EN2 += N2*(clock-prev);
            EN3 += N3*(clock-prev);
            if(N1>0) U1+=1*(clock-prev);
            if(N2>0) U2+=1*(clock-prev);
            if(N3>0) U3+=1*(clock-prev);

            switch (CurrentEvent->type){
            case ARR:
               if(uni_rv()<rs1)
               {
			      ///EN1 += N1*(clock-prev);  /////
                  N1 += 1;
                  Elist.insert(clock+exp_rv(lambda),ARR);
                  if(N1==1)
                  {
                    Elist.insert(clock+exp_rv(mu1),DEP1);  // A DEPARTURE FROM QUEUE1
                  }
               }
              else
               {
                  N2+=1;
                  Elist.insert(clock+exp_rv(lambda),ARR);
                  if(N2==1)
                  {
                    Elist.insert(clock+exp_rv(mu2),DEP2);  //A DEPARTURE FROM QUEQUE2
                  }
               }
               break;

            case DEP1:
			    ///EN1 += N1*(clock-prev);  
                N1-=1;
                Ndep1+=1;
                if(N1>0)
                {
                     Elist.insert(clock+exp_rv(mu1),DEP1);
                }
                if(uni_rv()<r11)
                {
                    N1+=1;
                    if(N1==1)
                    {
                      Elist.insert(clock+exp_rv(mu1),DEP1);
                    }
                }
                else{
                    N3+=1;
                    if(N3==1)
                    {
                        Elist.insert(clock+exp_rv(mu3),DEP3);  //A DEPARTURE FROM QUEQUE3
                    }
                }
                break;

            case DEP2:
			     ///EN2 += N2*(clock-prev); 
                 N2-=1;
                 Ndep2+=1;
                 N3+=1;
                 if(N3==1)
                 {
                    Elist.insert(clock+exp_rv(mu3),DEP3);
                 }
                 if(N2>0)
                 {
                     Elist.insert(clock+exp_rv(mu2),DEP2);
                 }
                 break;

            case DEP3:
			      ///EN3 += N3*(clock-prev);
                  N3-=1;
                  Ndep3+=1;
                  if(uni_rv()<=r3d)
                  {
                      Ndep_system+=1;
                  }
                  else{
                    N2+=1;
                    if(N2==1)
                    {
                        Elist.insert(clock+exp_rv(mu2),DEP2);
                    }
                  }
                  if(N3>0)
                  {
                      Elist.insert(clock+exp_rv(mu3),DEP3);
                  }
                  break;
            }

            delete CurrentEvent;

            if (Ndep_system > 500000)   done=1;
		}
		// output simulation results
  cout << "lambda: " << lambda << endl;
  cout << "Throughput of each queue(simulation): \n" << Ndep1/clock << endl << Ndep2/clock << endl << Ndep3/clock<< endl;
  cout << "Expected # of each queue(simulation): \n" << EN1/clock <<endl << EN2/clock << endl << EN3/clock << endl;
  cout << "Expected time of each queue(simulation): \n" << EN1/(double)Ndep1 << endl << EN2/(double)Ndep2 << endl << EN3/(double)Ndep3 <<endl;
  cout << "Utilization of each queue(simulation): \n" << U1/clock << endl << U2/clock << endl << U3/clock << endl;
 

}