Solved

Adding a second array in C++

Posted on 2011-02-14
15
753 Views
Last Modified: 2012-05-11
For statistics purposes, based on time – time is entered and percentage of "special customers" (who will be added into their own queue, based on the percentage).  I'm trying to add a second queue (specCustQueue) that will be looked at first; if nobody is in that queue, program should look to first queue (customerQueue) and handle customers from that queue.  Highlighted areas are the places in the code where this is trying to be implemented.  Can anyone see what else is needed/missing to make this operable?

The code is below, but if you open the attached word document, the areas that need to be altered are highlighted.


#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 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;
      int percentageSpecialCustomers;

      if ((static_cast<double> (rand()) / static_cast<double>(RAND_MAX)) < percentageSpecialCustomers)
            {
//                  specCustQueue.addQueue(customer);
                  return (value > exp(- 1.0/arvTimeDiff));
            }
      else
            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 totalWaitTimeServedCustomers = 0;
      int totalWaitTimeServedSpecialCustomers=0;
      int totalWaitTime = 0;
      int numberOfCustomersServed = 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();

            if(isCustomerArrived(timeBetweenCustomerArrival))
            {
                  custNumber++;
                  customer.setCustomerInfo(custNumber,clock,0,
                                                       transactionTime);
                  customerQueue.addQueue(customer);
                  specCustQueue.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, specCustQueue,
                                 custNumber, totalWaitTimeServedCustomers,
                                 totalWaitTimeServedSpecialCustomers);
}

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

      int totalWaitTime = waitTimeServedCustomers;
      int totalWaitTimeSpecial = waitTimeServedSpecialCustomers;

      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;
      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<<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(numOfCustArrived > 0)  // If number of customers arrived is > 0
            averageWaitTimeSpecial = (static_cast<double>(totalWaitTimeSpecial)) / numOfCustArrived;

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

}

here97.doc
0
Comment
Question by:Member_2_4213139
  • 8
  • 7
15 Comments
 
LVL 32

Expert Comment

by:sarabande
ID: 34888223
the statement

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

in the else branch will be different from that you checked in the if condition. (it already is the next random number). is that intended?

Sara

0
 

Author Comment

by:Member_2_4213139
ID: 34888495
That statement

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

 is for the regular customers and their queue (customerQueue) ... the special customers who go into their own queue (specCustQueue) should have their own random value of entering...

The special customers should enter their cue randomly, as the regular customers...
0
 
LVL 32

Expert Comment

by:sarabande
ID: 34888551
the code you posted firstly operates on regular customers and then on special customers.

is the updateWaitingQueue a blocking function?

can you explain what goes wrong or what do you expect to happen?

Sara
0
 

Author Comment

by:Member_2_4213139
ID: 34888868
When run, the code creates a number of customers, based on the time factor and waiting time, and inserts them into an array (customerQueue) at random time factors.  What I'm trying to do with the code is create a second array (specCustQueue) for a percentage of those customers (as determined by an input percentage) to go into the second queue and be deemed "special customers" with that second queue looked at and handled first by the servers (if there are any customers in there).  If no customers are in the special queue, the servers simply take customers from the first queue.  But the second queue must be looked at continuously, in order to determine if there are any "special customers" waiting.
0
 

Author Comment

by:Member_2_4213139
ID: 34888902
one additional note - If you would like the other parts of the code, to see what it looks like to run, I can provide them.  Right now, I'm not able to get the second queue to operate properly.
0
 
LVL 32

Expert Comment

by:sarabande
ID: 34888997
in the function runSimulation i can't see any code where you would handle queue entries of special queue.

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

Open in new window


and whenever you found one customer in regular queue you remove it from regular queue and delete (????) the queue. so if i see it rightly your customerQueue has one customer on maximum and new customer was added to specCustQueue but never evaluated.

Sara
0
 

Author Comment

by:Member_2_4213139
ID: 34889195
Naturally, I don't want to delete the queue!  I'm trying to get a percentage of the regular customers channeled into that second queue, and then have the second queue looked at first before the first queue.  I've tried several different things, and I've cut/pasted the text... what I gave you is the cleanest I've left it at!  :)
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 32

Expert Comment

by:sarabande
ID: 34889271
but there is no code that evaluates the special queue. at least that is true for function runSimulation.

Sara
0
 

Author Comment

by:Member_2_4213139
ID: 34889825
I had some there, but it was removed.  I tried to put a container (while statement) around the regular customer portion, but that didn't work out too well.  I'm hoping that you have a better idea as to how to do it.
0
 
LVL 32

Expert Comment

by:sarabande
ID: 34890692
normally you would poll both queues in an infinite loop. you also could add entries to the queues in same loop though i would prefer a thread which would do the adding.

with one thread it might look like (pseudocode only)

   while (true)
   {
       if (rand()%3 == 0)  // any third time add a new customer
       {
           if (rand()%3 == 0)  // any third to special queue
                add_random_customer_to_specialqueue();
           else
                add_random_customer_to_regularqueue();
      }
       if (rand()%7 == 0)  // any seventh time we evaluate both queues
       {
             if (!specialqueue.isempty())
                 handle_special_queue();
             if (!regularqueue.isempty())
                 handle_regular_queue();
       }
      sleep_a_little_while();
   }

the sleep is because otherwise the code would take 100 percent cpu time.

note if the customers have different priority you need a priority queue. that is a queue where the customers were sorted for a priority. your handle functions must not handle each customer in the queue but only those that cover a certain criteria.

Sara
0
 

Author Comment

by:Member_2_4213139
ID: 34891547
THANK YOU!  This is most helpful!  

The customers don't need a priority, just their own queues!  I wanted to do it that way, instead of using a priority queue, for future purposes (I have something in mind for a future revision).  

One last thing - how will this work in the statistics part?
0
 
LVL 32

Expert Comment

by:sarabande
ID: 34894618
the pseudocode i posted only showed how to simulate queuing. so you have some random inputs to either queue and a randomly issued handling part. as told it would be better if the input was added by one or more threads asynchronously cause that would better cover real life queuing.

the rand%3 and rand%7 will lead to a relative continuous flow of customers with little peaks and the times the objects would bein the queue is less than milliseconds (depending on sleep time). so in order to get realistic simulation (waiting) times you would need to refine the algorithm for input and output and move the milliseconds of the simulation to seconds or minutes. you also could add random 'handling times' for a single customer which needs to get added to the elapsed time (or you do a sleep for that time). you best would do all the functions into a class where you can keep the statistic data as members and have an output function to finally print them.

Sara

0
 

Author Comment

by:Member_2_4213139
ID: 34896670
I sent you the code, originally, so that you might fix it so that it works or show me what I need to fix.

Instead, you send me a general pseudocode of an algorithm that now, you say, only "simulates queueing."  

Would it be possible for you to help me further by showing me what code I need specifically and where it should go?


0
 
LVL 32

Accepted Solution

by:
sarabande earned 500 total points
ID: 34897122
i don't think your current code can be fixed. beside of the two queues there is nothing you could take as a base.

i also don't have enough information on what you really want to simulate to give you more than pseudocode for an abstract queuing mechanism. i can help you but not do the work for you.

so i would recommend you to specify your requirements on the simulation in normal words and not in technical terms and first of all not in code. based on that i (or others if you would post a new q.) can help you with the design. finally if you have a design you can try to implement and ask for help if you get a specific coding problem.

Sara
0
 

Author Closing Comment

by:Member_2_4213139
ID: 34897289
I wasn't very satisfied with the answer I received.  I am quite sure that a second array can be added to the existing code.  I am taking the advice of the expert, however, and posting this as a new question.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

The following diagram presents a diamond class hierarchy: As depicted, diamond inheritance denotes when two classes (e.g., CDerived1 and CDerived2), separately extending a common base class (e.g., CBase), are sub classed simultaneously by a fourt…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

746 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now