[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

C++ Program with Two Queues

Posted on 2011-02-15
4
Medium Priority
?
1,055 Views
Last Modified: 2012-05-11
This is a single queue program:

#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <cmath>

#include "Simulation.h"
#include "queueAsArray.h"

using namespace std;

void setSimulationParameters(int& sTime, int& numOfServers,
                                           int& transTime,
                                           int& tBetweenCArrival);
bool isCustomerArrived(double arvTimeDiff);

void generateStatistics(serverListType& serverList,
                                    waitingCustomerQueueType& CQueue,
                                    int numOfCustArrived,
                                    int waitTimeServedCustomers);
void runSimulation();

int main()
{
      runSimulation();

      system("pause");
      return 0;
}

void setSimulationParameters(int& sTime, int& numOfServers,
                                           int& transTime,
                                           int& tBetweenCArrival)
{
      cout<<"Enter the simulation time: "<<flush;
      cin>>sTime;
      cout<<endl;

      cout<<"Enter the number of servers: "<<flush;
      cin>>numOfServers;
      cout<<endl;

      cout<<"Enter the transaction time: "<<flush;
      cin>>transTime;
      cout<<endl;

      cout<<"Enter the time between customer arrivals: "<<flush;
      cin>>tBetweenCArrival;
      cout<<endl;
}

bool isCustomerArrived(double arvTimeDiff)
{
      double value;

      value = static_cast<double> (rand()) / static_cast<double>(RAND_MAX);

      return (value > exp(- 1.0/arvTimeDiff));
}

void runSimulation()
{
      
      int simulationTime;
      int numberOfServers;
      int transactionTime;
      int timeBetweenCustomerArrival;

      waitingCustomerQueueType customerQueue;

      customerType customer;

      int custNumber = 0;
      
      int totalWaitTimeServedCustomers = 0;
      int totalWaitTime = 0;
      int numberOfCustomersServed = 0;
      int customersLeftInServers = 0;
      int clock = 0;
      int serverID;

      setSimulationParameters(simulationTime, numberOfServers,
                    transactionTime, timeBetweenCustomerArrival);

      serverListType serverList(numberOfServers);

      for(clock = 1; clock <= simulationTime; clock++)
      {
            serverList.updateServers();

            if(!customerQueue.isEmptyQueue())
                  customerQueue.updateWaitingQueue();

            if(isCustomerArrived(timeBetweenCustomerArrival))
            {
                  custNumber++;
                  customer.setCustomerInfo(custNumber,clock,0,
                                                       transactionTime);
                  customerQueue.addQueue(customer);
                  cout<<"Customer number "<<custNumber
                        <<" arrived at time unit "<<clock<<endl;
            }
            
            serverID = serverList.getFreeServerID();
            if(serverID != -1 && !customerQueue.isEmptyQueue())
            {
                  customer = customerQueue.front();
                  customerQueue.deleteQueue();
                  totalWaitTimeServedCustomers = totalWaitTimeServedCustomers
                                                                  + customer.getWaitingTime();
                  serverList.setServerBusy(serverID, customer);
            }
      }

      cout<<endl;

      cout<<"Simulation ran for "<<simulationTime
            <<" time units"<<endl;
      cout<<"Number of servers: "<<numberOfServers<<endl;
      cout<<"Average transaction time: "
            <<transactionTime<<endl;
      cout<<"Average arrival time difference between customers: "
            <<timeBetweenCustomerArrival<<endl;

      generateStatistics(serverList, customerQueue,
                                 custNumber, totalWaitTimeServedCustomers);
}

void generateStatistics(serverListType& serverList,
                                    waitingCustomerQueueType& CQueue,
                                    int numOfCustArrived,
                                    int waitTimeServedCustomers)
{
      int customersLeftInQueue = 0;

      int totalWaitTime = waitTimeServedCustomers;

      customerType customer;

      while(!CQueue.isEmptyQueue())
      {
            customer = CQueue.front();
            CQueue.deleteQueue();
            totalWaitTime = totalWaitTime + customer.getWaitingTime();
            customersLeftInQueue++;
      }

                  //Find number of customers left in servers
      int customersLeftInServers = serverList.getNumberOfBusyServers();
                  //Find number of customers completely served
      int numberOfCustomersServed = numOfCustArrived - customersLeftInServers -
                                            customersLeftInQueue;

      double averageWaitTime = 0;

      cout<<"Total wait time: "<<totalWaitTime<<endl;
      cout<<"Number of customers who completed a transaction: "
            <<numberOfCustomersServed<<endl;
      cout<<"Number of customers left in the servers: "
            <<customersLeftInServers<<endl;
      cout<<"Number of customers left in the queue: "<<customersLeftInQueue
            <<endl;
            
      if(numOfCustArrived > 0)  // If number of customers arrived is > 0
            averageWaitTime = (static_cast<double>(totalWaitTime)) / numOfCustArrived;

      cout<<fixed<<showpoint;
      cout<<setprecision(2);
      cout<<"Average wait time: "<<averageWaitTime<<endl;
      cout<< endl;
      cout<<"************** END SIMULATION *************"<<endl;
      cout<< endl;

}

I want to add a second queue so that, when run, a user-input percentage of the customers will go into the second queue while the remainder of them will go into the first (original) queue.  PLEASE tell me what I have to do in order to make this code work with two queues.  (I have a code I've been working on, integrating the second array, but was told that it wasn't any good...)  If you'd like to see that, let me know and I'll post it.
0
Comment
Question by:Member_2_4213139
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
4 Comments
 

Author Comment

by:Member_2_4213139
ID: 34898064
And here is what I have so far (PLEASE tell me SPECIFICALLY where I've gone wrong and what to put in to fix it):

#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <cmath>

#include "Simulation.h"
#include "queueAsArray.h"

using namespace std;

void setSimulationParameters(int& sTime, int& numOfServers,
                                           int& transTime,
                                           int& tBetweenCArrival);

bool isCustomerArrived(double arvTimeDiff);

void generateStatistics(serverListType& serverList,
                                    waitingCustomerQueueType& CQueue,
                                    waitingCustomerQueueType& SQueue,
                                    int numOfCustArrived,
                                    int numOfSpecCustArrived,
                                    int waitTimeServedCustomers,
                                    int waitTimeServedSpecialCustomers);
void runSimulation();

int main()
{
      runSimulation();

      system("pause");
      return 0;
}

void setSimulationParameters(int& sTime, int& numOfServers,
                                           int& transTime,
                                           int& tBetweenCArrival,
                                           int& pSpecCust)
{
      cout<<"Enter the simulation time: "<<flush;
      cin>>sTime;
      cout<<endl;

      cout<<"Enter the number of servers: "<<flush;
      cin>>numOfServers;
      cout<<endl;

      cout<<"Enter the transaction time: "<<flush;
      cin>>transTime;
      cout<<endl;

      cout<<"Enter the time between customer arrivals: "<<flush;
      cin>>tBetweenCArrival;
      cout<<endl;

      cout<<"Enter the percentage of special customers: "<<flush;
      cin>>pSpecCust;
      cout<<endl;
}

bool isCustomerArrived(double arvTimeDiff)
{
      double value;

      value = static_cast<double> (rand()) / static_cast<double>(RAND_MAX);

      return (value > exp(- 1.0/arvTimeDiff));
}

void runSimulation()
{
      
      int simulationTime;
      int numberOfServers;
      int transactionTime;
      int timeBetweenCustomerArrival;
      int percentageSpecialCustomers;

      waitingCustomerQueueType customerQueue;
      waitingCustomerQueueType specCustQueue;

      customerType customer;

      int custNumber = 0;
      int specCustNumber = custNumber;
      
      int totalWaitTimeServedCustomers = 0;
      int totalWaitTimeServedSpecialCustomers=0;
      int totalWaitTime = 0;
      int numberOfCustomersServed = 0;
      int numberOfSpecialCustomersServed = 0;
      int customersLeftInServers = 0;
      int clock = 0;
      int serverID;

      setSimulationParameters(simulationTime, numberOfServers,
                    transactionTime, timeBetweenCustomerArrival, percentageSpecialCustomers);

      serverListType serverList(numberOfServers);

      for(clock = 1; clock <= simulationTime; clock++)
      {
            serverList.updateServers();

            if(!customerQueue.isEmptyQueue())
                  customerQueue.updateWaitingQueue();

            if(!specCustQueue.isEmptyQueue())
                  specCustQueue.updateWaitingQueue();      
            
            while(isCustomerArrived(timeBetweenCustomerArrival))
            
                  if ((static_cast<double> (rand()) / static_cast<double>(RAND_MAX)) < percentageSpecialCustomers)
                        {
                              custNumber++;
                              customer.setCustomerInfo(custNumber,clock,0,
                                                             transactionTime);
                                                      
                              specCustQueue.addQueue(customer);

                        cout<<"Customer number "<<custNumber
                              <<" arrived at time unit "<<clock<<endl;
                        }
                  else
                  {
                        custNumber++;
                        customer.setCustomerInfo(custNumber,clock,0,
                                                             transactionTime);

                        customerQueue.addQueue(customer);

                        cout<<"Customer number "<<custNumber
                              <<" arrived at time unit "<<clock<<endl;
                  }
            
            serverID = serverList.getFreeServerID();

            while (serverID != -1 && !specCustQueue.isEmptyQueue())
                  {
                        customer = specCustQueue.front();
                        specCustQueue.deleteQueue();
                        totalWaitTimeServedCustomers = totalWaitTimeServedSpecialCustomers
                                                                        + customer.getWaitingTime();
                        serverList.setServerBusy(serverID, customer);
                  }

                  if(serverID != -1 && !customerQueue.isEmptyQueue())
                  {
                        customer = customerQueue.front();
                        customerQueue.deleteQueue();
                        totalWaitTimeServedCustomers = totalWaitTimeServedCustomers
                                                                        + customer.getWaitingTime();
                        serverList.setServerBusy(serverID, customer);
                  }
      }

      cout<<endl;

      cout<<"Simulation ran for "<<simulationTime
            <<" time units"<<endl;
      cout<<"Number of servers: "<<numberOfServers<<endl;
      cout<<"Average transaction time: "
            <<transactionTime<<endl;
      cout<<"Average arrival time difference between customers: "
            <<timeBetweenCustomerArrival<<endl;

      generateStatistics(serverList, customerQueue, specCustQueue,
                                 custNumber, specCustNumber,
                                 totalWaitTimeServedCustomers,
                                 totalWaitTimeServedSpecialCustomers);
}

void generateStatistics(serverListType& serverList,
                                    waitingCustomerQueueType& CQueue,
                                    waitingCustomerQueueType& SQueue,
                                    int numOfCustArrived,
                                    int numOfSpecCustArrived,
                                    int waitTimeServedCustomers,
                                    int waitTimeServedSpecialCustomers)
{
      int customersLeftInQueue = 0;
      int specialCustomersLeftInQueue = 0;

      int totalWaitTime = waitTimeServedCustomers;
      int totalWaitTimeSpecial = waitTimeServedSpecialCustomers;

      customerType customer;

      while(!SQueue.isEmptyQueue())
      {
            customer = SQueue.front();
            SQueue.deleteQueue();
            totalWaitTimeSpecial = totalWaitTimeSpecial + customer.getWaitingTime();
            specialCustomersLeftInQueue++;
      }

      if(!CQueue.isEmptyQueue())
      {
            customer = CQueue.front();
            CQueue.deleteQueue();
            totalWaitTime = totalWaitTime + customer.getWaitingTime();
            customersLeftInQueue++;
      }

                  //Find number of customers left in servers
      int customersLeftInServers = serverList.getNumberOfBusyServers();
                  //Find number of customers completely served
      int numberOfCustomersServed = numOfCustArrived - customersLeftInServers -
                                            customersLeftInQueue;
      int numberOfSpecialCustomersServed = numOfCustArrived - customersLeftInServers -
                                            specialCustomersLeftInQueue;

      double averageWaitTime = 0;
      double averageWaitTimeSpecial = 0;

      cout<<"Number of customers who completed a transaction: "
            <<numberOfCustomersServed<<endl;
      cout<<"Number of customers left in the servers: "
            <<customersLeftInServers<<endl;
      cout<<"Number of customers left in the queue: "<<customersLeftInQueue
            <<endl;
      cout<<"Number of special customers left in the queue: "<<specialCustomersLeftInQueue
            <<endl;
      cout<<endl;
      cout<<endl;
      cout<<"Total wait time - Regular Customers: "<<totalWaitTime<<endl;

      if(numOfCustArrived > 0)  // If number of customers arrived is > 0
            averageWaitTime = (static_cast<double>(totalWaitTime)) / numOfCustArrived;

      cout<<fixed<<showpoint;
      cout<<setprecision(2);
      cout<<"Average wait time - Regular Customers: "<<averageWaitTime<<endl;
      cout<< endl;

            cout<<"Total wait time - Special Customers: "<<totalWaitTimeSpecial<<endl;

      if(numOfSpecCustArrived > 0)  // If number of special customers arrived is > 0
            averageWaitTimeSpecial = (static_cast<double>(totalWaitTimeSpecial)) / numOfSpecCustArrived;

      cout<<fixed<<showpoint;
      cout<<setprecision(2);
      cout<<"Average wait time - Special Customers: "<<averageWaitTimeSpecial<<endl;
      cout<< endl;
      cout<< endl;
      cout<<"************** END SIMULATION *************"<<endl;
      cout<< endl;

}
0
 
LVL 16

Accepted Solution

by:
HooKooDooKu earned 1500 total points
ID: 34898424
At least one issue I think I see is the way you are trying to divide the work between the two queues:

It looks like logic for the random number generator is going to send all the work to ' specCustQueue' unless 'percentageSpecialCustomers' is zero..

Won't the logic "rand() / RAND_MAX" create a floating point number between zero and 1?  Yet you are comparing this result to an integer variable (presumably filled with a whole number from 0 to 100).

Logically, you want something like...
if( rand() * 100 / RAND_MAX < percentageSpecialCustomers )
...but the results will be skewed a little bit because of rounding errors, you might need to tweak the result with something like...
if( (rand() * 100 + RAND_MAX / 2 ) / RAND_MAX < percentageSpecialCustomers )
... are just a few ways to correct the mistake.
0
 

Author Comment

by:Member_2_4213139
ID: 34898735
THAT was most helpful!  

I know it would have been better to use a high priority queue, but I wanted a second queue for other modifications I may do in the future.

For some reason, in the end of the program, it's not reading the statistics for the special customers...
0
 

Author Closing Comment

by:Member_2_4213139
ID: 34906736
This solution pointed out one problem... however, there are a couple more.
0

Featured Post

Survive A High-Traffic Event with Percona

Your application or website rely on your database to deliver information about products and services to your customers. You can’t afford to have your database lose performance, lose availability or become unresponsive – even for just a few minutes.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This is about my first experience with programming Arduino.
In this post we will learn how to make Android Gesture Tutorial and give different functionality whenever a user Touch or Scroll android screen.
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
Starting up a Project
Suggested Courses

656 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question