Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

IN C#: Below is the Instructions for this program that I need to do. It is Queues: Customer Processing. INSTRUCTIONS: Problem When we are waiting

IN C#:

Below is the Instructions for this program that I need to do. It is Queues: Customer Processing.

INSTRUCTIONS:

Problem

When we are waiting in a fast food line, an airline service counter, a bank, etc. there is typically one of two different methods of managing customers:

Have a single line for people waiting for service. Every customer waits in a single line. When a teller becomes free, the customer at the head of the line moves to the teller. If there are multiple tellers free, one is picked randomly.

Have multiple lines one for each teller. When customers come in the door they attempt to pick the line that has the shortest wait. This usually involves standing in the line with the fewest customers. If there are multiple choices, the appropriate line is selected randomly.

So, which of these two methods of queuing customers is most efficient? In the single-line technique, tellers appear to be constantly busy and no customer is served before any customer that arrives later. In the multiple-line technique, however, customers can take the responsibility of evaluating the lines themselves.

Procedure

Attached to this assignment in the drop box are three files. One models a Customer, one models a customer generator (e.g. the front door of a bank) and the final models the bank itself (which contains the Main method). The Main method is really just a shell to demonstrate calling the customer generator. The generator accepts the following arguments:

minDuration The minimum amount of time that it will take to process a customer's request.

maxDuration The maximum amount of time that it will take to process a customer's request.

avgPerSlot The average number of customers that will arrive per time slot. (e.g. .5 would mean one customer every two minutes; 3 would mean three customers per minute)

totalTime Total number of time slots for which customers are to be generated. For example, 120 means a two hour timeslot. The time will actually be slightly longer to service the last few customers.

seed If present, the this value is passed as the seed to the random number generator. If the seed is negative, no seed is passed.

For the sake of this program, all time units represent one minute, though as long as the unit is consistent throughout the program, this could be any time (second, millisecond, day, etc.) The class has a single method, GetCustomers, which returns a Queue of customers now waiting to be served. You could think of it as the all the customers who arrived in the last minute. That method takes a single argument, timeslot, which is the number of seconds that have elapsed during the simulation. The precise working of the CustomerGenerator isn't important for the assignment, but if you are curious you have the code.

For this assignment you will not need to create a Customer since the CustomerGenerator will do that, but you will need to access its properties. Two of these are set when the Customer is created and cannot be modified. You will want to set the service time when the Customer actually reaches teller.

Begin your assignment using these three files.

For a grade of 'C':

We want to know how many tellers it takes so that no customer ever has to wait more than five minutes in line before being waited on. To get at this, and some other information our employer wants, we want to display the maximum minutes a teller was idle, the average minutes a teller was idle, the maximum minutes a customer had to wait and the average minutes a customer had to wait. (These last two need to be calculated on the fly, we aren't going to make all the customers wait in line until the day is over and ask them how long they waited.)

You are going to need a Teller class. At a minimum, the Teller class should keep track of how much time it spends in the idle state, i.e. w/o having an active customer. It must also have some way to process a customer. To make things easier, I also suggest that the Teller have a reference to a Queue of customers so that it can pull the next customer off the queue. That will make moving to the work for a B easier as well. I also encourage you to have a reference to the currentCustomer. You will also want a processNextCustomer method see below.

I'll leave most of the details up to you, but here is a very high level view of your process.

Create an empty Queue of customers

Create a CustomerGenerator.

Create a list of Tellers start with some reasonable size, then modify the number until you have the fewest number of tellers but still have no wait time greater than five minutes. Note your code does not have to do figure this out; you can experiment until you find the right answer. Think carefully and you should be able to determine a good starting point based on the parameters passed to the CustomerGenerator constructor.

Set the currentMinute to zero.

Loop until the time duration expires AND the Queue is empty, performing the following

get the list of customers from the customer generator for that minute

add them to the Queue of customers

foreach teller in the listhave the teller process a customer (processNextCustomer)

the method should accept the current time as its argument

it should check to see whether it is still busy (Question: how does it know whether it is busy?) with an earlier customer; there are three possibilities

busy

return w/o doing anything

not busy:

it should pull a customer off the queue and assign a reference to an internal Customer object

it should set the time of the customers service time to the current time

not busy but the queue is empty

it should increment its idle time

Increment the current time

End Loop

Print the parameters, appropriately labeled, that were passed to the CustomerGenerator...this defines the beginning state.

Print the values described above (highest wait time, average wait time, highest idle time, average idle time)

Print the number of customers serviced and the total time taken.

For a grade of B:

Add the multiple-line simulation, one line per Teller. You can do this in two completely different Banks if you prefer, but you may find that it is pretty simple to have a flag that you can flip to have your code process multiple queues. They are very similar. Rather than a single queue you will want one queue for each teller (think List>). The part of the code which gets the Queue from the customer generator will determine which queue has the fewest customers and add the customer to that queue. If there is a tie, it doesn't matter which one gets it. (To be fair, you should do round-robin scheduling but that is more trouble that it is worth; just hand it to the first teller in the list.)

Thought Questions

Consider the following questions as you complete the assignment:

Run several simulations of both types of queues. Which queue strategy seems to process all the customers fastest? Is the number of required tellers the same? If not, which algorithm requires the fewest tellers?

Is there a difference between the average wait-time for customers between the two techniques?

Is there a difference between the average/max idle-time for Tellers between the two techniques?

For a grade of A:

Wrap your Queue of customers (or if you are brave, extend the Queue class) into a class that can keep track of the total of the TransactionDurations of all the customers in the queue. Don't walk the queue, simply keep track by adding to the number when Enqueue is called and subtracting from the number when Dequeue is called. Change the algorithm so that when a new customer 'arrives' they are placed into the queue with the shortest total of TransactionDurations rather than the line with the fewest customers. Keep the number of tellers the same as you did for the 'B' portion.

More Questions:

What do you notice?

What does this say about choosing a line based on length, say at a bank, vs. choosing a line at a grocery store where you can see the number of items in the customers' carts?

Notes

I strongly encourage you to get the work for a C working well before attempting to move on to the B and A assignments. If you have thought through the original assignment well, and work out all the bugs at that stage, adding the extra features is actually quite simple. Think hard about how to represent your single queue so that it could be easily expanded to multiple queues.

Here are the files that came with the program. I also need to answer the questions that are along with a grade of 'B' and a grade of 'A'.

Teller.cs:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;

namespace CSAQueue { public class Teller { // our quueue of customers private Queue custQ; // the tick of the clock when the teller becomes free private int nextFree = 0;

// the amount of time the teller is idle public int IdleTime { get; private set; }

// the number of customers served public int CustomersServed { get; private set; }

// the longest time that one of this teller's customers has waited public int MaxWaitTime { get; private set; }

// the total amount of time that all of this teller's customers have waited public int TotalWaitTime { get; private set; }

// Constructor accepts the queue of customers from which to pull the next customer // There are other ways to do this, but this makes part B less painful public Teller(Queue q) { custQ = q; }

///

/// Begins helping a customer if the teller is not busy AND a customer is waiting /// /// The time on the bank's clock, in minutes from the start, i.e. timeslot. public void ProcessNextCustomer(int now) { // busy? if (now >= nextFree) { /* TODO -- work out the code for the following pseudocode if anyone is waiting { pull a customer from the queue figure out the next time the teller will be free based on the TransactionDuration update the customers, total wait time and (possibly) the largest wait time Note: you'll need information from the customer how long she has been waiting } else { increment the idle time } */ } } } }

CustomerGenerator.cs:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;

namespace CSAQueue { ///

/// Generates a stream of randomly arriving customers. /// public class CustomerGenerator { private int[] customerArrivals; private readonly int minDuration; private readonly int maxDuration; private Random rand;

///

/// Creates the generator and initializes the random number generator for populating the customer queues. /// /// The minimum amount of time that it will take to process a customer's request. /// The maximum amount of time that it will take to process a customer's request. /// The average number of customers that will arrive per time slot. /// Total number of time slots for which customers are to be generated. /// If present, the this value is passed as the seed to the random number generator. If the seed is negative, no seed is passed. public CustomerGenerator(int minDuration, int maxDuration, double avgPerSlot, int totalTime, int seed=-1) { if (seed < 0) rand = new Random(); else rand = new Random(seed);

customerArrivals = new int[totalTime]; this.minDuration = minDuration; this.maxDuration = maxDuration; initializeArrivals(avgPerSlot, totalTime); }

///

/// Initializes an array containing the number of customers that will be generated for each time slot. /// /// The average number of customers that will arrive per time slot. /// Total number of time slots for which customers are to be generated. private void initializeArrivals(double avgPerSlot, int slots) { for (int i = 0; i < slots * avgPerSlot; i++) { int slot = rand.Next(slots); customerArrivals[slot]++; } }

///

/// Returns a Queue of customers that are generated for the given time slot. /// /// The time slot for which the customers are to be generated. /// The Queue of customers. This queue may be empty. public Queue GetCustomers(int timeSlot) { Queue customers = new Queue();

// Make cettain we haven't gone beyond the time; this could happen whlle // the queue of waiting customers is emptied if (timeSlot < customerArrivals.Length) { // Our pre-generated array contains the number of customers for any given timeslot int numArrivals = customerArrivals[timeSlot];

while (numArrivals > 0) { int duration = rand.Next(maxDuration - minDuration + 1) + minDuration; Customer customer = new Customer(timeSlot, duration); customers.Enqueue(customer); numArrivals--; } } return customers; } }

Customer.cs:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;

namespace CSAQueue { ///

/// Keeps track of the arrival time, the time the service of the customer begins and the expected duration of the transaction, i.e. how long it will take to perform the customer's request. /// public class Customer { // The time (i.e. minutes from the start of the simulation) that the customer arrives public readonly int ArrivalTime;

// The number of minutes that it will take to service this customer public readonly int TransactionDuration; // The time (minutes from the start) that the customer actually gets to see a Teller; depending on your // implementation, this may not be needed. public int ServiceTime { get; set; }

// The constructor is called from the generator; you never need to create a customer public Customer(int arrival, int duration) { ArrivalTime = arrival; TransactionDuration = duration; }

// For debugging purposes public override String ToString() { StringBuilder builder = new StringBuilder(); builder.Append("Customer [arrivalTime="); builder.Append(ArrivalTime); builder.Append(", transactionDuration="); builder.Append(TransactionDuration); builder.Append(", serviceTime="); builder.Append(ServiceTime); builder.Append("]"); return builder.ToString(); } }

}

Bank.cs:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;

namespace CSAQueue { class Bank { public static void Main(string[] args) { // shortest time to service a customer; must be greater than zero int MINIMUM_DURATION = 1;

// longest time to service a customer; must be greater than the minimum duration int MAXIMUM_DURATION = 5;

// average customers arriving per given minute. This would mean three customers every four minutes. double CUST_PER_MINUTE = .75;

// how long the simulation represents; 120 would equal two hours int SIMULATION_DURATION = 120;

// The number of tellers for this run of the simulation // int NUM_TELLERS = 15;

// Create the customer generator CustomerGenerator frontdoor = new CustomerGenerator(MINIMUM_DURATION, MAXIMUM_DURATION, CUST_PER_MINUTE, SIMULATION_DURATION);

// TODO -- Create a List (not a Queue) of Teller objects; the number of // tellers in the list is what you should modify to determine how // many tellers are necessary. You'll need to populate the list, of course. // Continue looping until we have completed the duration of our simulation // timeslot represents the number of minutes since the start of our simulation // TODO -- modify the loop so that it continues to run until there is noone left in line for (int timeSlot = 0; timeSlot < SIMULATION_DURATION; timeSlot++) { // get the queue of arriving customers from the frontdoor Queue arrivals = frontdoor.GetCustomers(timeSlot); // TODO -- in a loop, move all of the customers from the arrival queue to the Queue of waiting customers /// be careful that you do not try to pull too many customers from the Queue // TODO -- for every teller (think foreach), call ProcessNextCustomer(timeSlot) } // TODO -- print the statistics // You'll need to walk through your list of Tellers figuring out longest wait time, total wait time, etc.

Console.ReadLine(); } } }

Most of the work needs to be done in the Bank.cs class but there is also some work that needs to be done in the Teller.cs class as well.

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image_2

Step: 3

blur-text-image_3

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

More Books

Students also viewed these Databases questions