public int CompareTo(Object obj) { if (!(obj is Evnt)) { throw new ArgumentException("The argument is not an Event Object"); } Evnt e = (Evnt)obj; return(e.Time.CompareTo(Time)); }
/// <summary> /// Does the simulation. /// </summary> /// <param name="ExpectedRegistrants">The expected registrants.</param> /// <param name="NumberOfHoursOpen">The number of hours open.</param> /// <param name="NumberOfQueues">The number of queues.</param> /// <param name="ExpectedRegistrationTime">The expected registration time.</param> public static void DoSimulation(int ExpectedRegistrants, int NumberOfHoursOpen, int NumberOfQueues, double ExpectedRegistrationTime) { TimeSpan tick = new TimeSpan(1000000); //tick = .1 sec DateTime openTime = new DateTime(2016, 11, 1, 8, 0, 0, 0); TimeSpan hoursOpenTimeSpan = new TimeSpan(NumberOfHoursOpen, 0, 0); DateTime closingTime = new DateTime(2016, 11, 1, 8, 0, 0, 0); closingTime += hoursOpenTimeSpan; MaxWindowTime = new TimeSpan(0, 0, 0, 0); MinWindowTime = new TimeSpan(100, 100, 100, 100); int actualNumRegistrants = Poisson(ExpectedRegistrants); //actual number of registrants List <int> patronIdListFromPoisson = new List <int>(actualNumRegistrants); for (int i = 0; i < actualNumRegistrants; i++) { patronIdListFromPoisson.Add(i); } RandomizeList(patronIdListFromPoisson); TimeSpan enterConvetionTimer = new TimeSpan(hoursOpenTimeSpan.Ticks / actualNumRegistrants); //how often people enter the convention double tickNumTrigger = enterConvetionTimer.Ticks / tick.Ticks; int numberOfTotalTicks = (int)(hoursOpenTimeSpan.Ticks / tick.Ticks); //how often people enter the convention List <int> entranceTimesInTicks = new List <int>(actualNumRegistrants); for (int i = 0; i < actualNumRegistrants; i++) { entranceTimesInTicks.Add(ran.Next(numberOfTotalTicks)); } entranceTimesInTicks.Sort(); DateTime currentTime = openTime; List <Queue <Registrants> > listOfQs = new List <Queue <Registrants> >(NumberOfQueues); for (int i = 0; i < NumberOfQueues; i++) { listOfQs.Add(new Queue <Registrants>()); } Queue <Registrants> expectedRegistrants = new Queue <Registrants>(actualNumRegistrants); for (int i = 0; i < actualNumRegistrants; i++) { expectedRegistrants.Enqueue(new Registrants(patronIdListFromPoisson[i])); } PriorityQueue <Evnt> PQ2 = new PriorityQueue <Evnt>(); Evnt[] PQArr = new Evnt[NumberOfQueues]; testLeaveWin = 0; counterPatrons = 0; longestQ = 0; int tickCounter = 0; while (!((currentTime > closingTime) && counterPatrons == testLeaveWin))//&& counterPatrons == testLeaveWin { while (counterPatrons != actualNumRegistrants && entranceTimesInTicks[counterPatrons] == tickCounter) { GetShortestLine(listOfQs, expectedRegistrants); }//end while to find the shortest line while (PQ2.Count > 0 && PQ2.Peek().Depart <= currentTime) { int lineChoice = GoToPriorityQueue(listOfQs, PQ2, PQArr); //if there is someone next in that line, they enter the PQ (approach the window) and are assigned a wait time if (listOfQs[lineChoice].Count > 0) { listOfQs[lineChoice].Peek().Arrival = new Evnt(currentTime, lineChoice, listOfQs[lineChoice].Peek().PatronNum, ExpectedRegistrationTime); //assign wait time PQ2.Enqueue(listOfQs[lineChoice].Peek().Arrival); //new patron enters PQ (approaches window) PQArr[lineChoice] = listOfQs[lineChoice].Peek().Arrival; }//end if of patron entering displayQs(listOfQs); }//end while for window departure //This fills the PQ initially, otherwise they are //pulled into the PQ when someone leaves. EnterPriorityQueue(ExpectedRegistrationTime, currentTime, listOfQs, PQ2, PQArr); tickCounter++; currentTime = currentTime.Add(tick); } //summary at end double avgTime = (totalTime.TotalSeconds / testLeaveWin) / 60; displayQs(listOfQs); string avgTimes = ""; avgTimes += "The average service time for " + testLeaveWin + " Registrants was " + avgTime.ToString("0.##") + "."; Console.WriteLine(avgTimes); totalTime = new TimeSpan(); Console.WriteLine(("Maximum Window Time: ") + ("{0:%h} hours {0:%m} minutes {0:%s} seconds"), MaxWindowTime); Console.WriteLine(("Minimum Window Time: ") + ("{0:%h} hours {0:%m} minutes {0:%s} seconds"), MinWindowTime); }
/// <summary> /// Does the simulation without display. /// </summary> /// <param name="ExpectedRegistrants">The expected registrants.</param> /// <param name="NumberOfHoursOpen">The number of hours open.</param> /// <param name="NumberOfQueues">The number of queues.</param> /// <param name="ExpectedRegistrationTime">The expected registration time.</param> static void DoSimulationWithoutDisplay(int ExpectedRegistrants, int NumberOfHoursOpen, int NumberOfQueues, double ExpectedRegistrationTime) { TimeSpan tick = new TimeSpan(1000000); //tick = .1 sec DateTime openTime = new DateTime(2016, 11, 1, 8, 0, 0, 0); TimeSpan hoursOpenTimeSpan = new TimeSpan(NumberOfHoursOpen, 0, 0); DateTime closingTime = new DateTime(2016, 11, 1, 8, 0, 0, 0); closingTime += hoursOpenTimeSpan; int actualNumRegistrants = Poisson(ExpectedRegistrants); //actual number of registrants List <int> patronIdListFromPoisson = new List <int>(actualNumRegistrants); for (int i = 0; i < actualNumRegistrants; i++) { patronIdListFromPoisson.Add(i); } RandomizeList(patronIdListFromPoisson); TimeSpan enterConvetionTimer = new TimeSpan(hoursOpenTimeSpan.Ticks / actualNumRegistrants); //how often people enter the convention double tickNumTrigger = enterConvetionTimer.Ticks / tick.Ticks; int numberOfTotalTicks = (int)(hoursOpenTimeSpan.Ticks / tick.Ticks); //how often people enter the convention List <int> entranceTimesInTicks = new List <int>(actualNumRegistrants); for (int i = 0; i < actualNumRegistrants; i++) { entranceTimesInTicks.Add(ran.Next(numberOfTotalTicks)); } entranceTimesInTicks.Sort(); DateTime currentTime = openTime; List <Queue <Registrants> > listOfQs = new List <Queue <Registrants> >(NumberOfQueues); for (int i = 0; i < NumberOfQueues; i++) { listOfQs.Add(new Queue <Registrants>()); } Queue <Registrants> expectedRegistrants = new Queue <Registrants>(actualNumRegistrants); for (int i = 0; i < actualNumRegistrants; i++) { expectedRegistrants.Enqueue(new Registrants(patronIdListFromPoisson[i])); } PriorityQueue <Evnt> PQ2 = new PriorityQueue <Evnt>(); Evnt[] PQArr = new Evnt[NumberOfQueues]; int failDQCounter = 0; testLeaveWin = 0; counterPatrons = 0; longestQ = 0; int tickCounter = 0; while (!((currentTime > closingTime) && counterPatrons == testLeaveWin)) { while (counterPatrons != actualNumRegistrants && entranceTimesInTicks[counterPatrons] == tickCounter) { expectedRegistrants.Peek().lineChoice = GetShortestLine(listOfQs); listOfQs[expectedRegistrants.Peek().lineChoice].Enqueue(expectedRegistrants.Dequeue()); if (longestQ < LongestLine(listOfQs)) //save the length of longest Queue { longestQ = LongestLine(listOfQs); } //displayQs(listOfQs); counterPatrons++; } while (PQ2.Count > 0 && PQ2.Peek().Depart <= currentTime) //check if the top of PQ should depart { int lineChoice = PQ2.Peek().LineChoice; //remember which queue the patron is leaving from totalTime += PQ2.Peek().windowTime; PQ2.Dequeue(); //the patron leaves the PQ (window) testLeaveWin++; listOfQs[lineChoice].Dequeue(); //the patron leaves the queue (line they were waiting in) PQArr[lineChoice] = null; //if there is someone next in that line, they enter the PQ (approach the window) and are assigned a wait time if (listOfQs[lineChoice].Count > 0) { listOfQs[lineChoice].Peek().Arrival = new Evnt(currentTime, lineChoice, listOfQs[lineChoice].Peek().PatronNum, ExpectedRegistrationTime); //assign wait time PQ2.Enqueue(listOfQs[lineChoice].Peek().Arrival); //new patron enters PQ (approaches window) PQArr[lineChoice] = listOfQs[lineChoice].Peek().Arrival; } }//end while for window departure //This fills the PQ initially, otherwise they are //pulled into the PQ when someone leaves. if (PQ2.Count < listOfQs.Count) //if the PQ (windows) are not full { for (int i = 0; i < listOfQs.Count; i++) //for every queue { if (listOfQs[i].Count > 0 && PQ2.Count < listOfQs.Count) //if theres someone in the i'th Q and PQ2 is still not full { bool duplicate = false; for (int j = 0; j < listOfQs.Count; j++) { if (PQArr[j] != null && listOfQs[i].Peek().PatronNum == PQArr[j].Patron) { duplicate = true; } } if (!duplicate) { listOfQs[i].Peek().Arrival = new Evnt(currentTime, i, listOfQs[i].Peek().PatronNum, ExpectedRegistrationTime); //and gets window wait time PQ2.Enqueue(listOfQs[i].Peek().Arrival); //First in line enters PQ PQArr[i] = listOfQs[i].Peek().Arrival; } } } } tickCounter++; currentTime = currentTime.Add(tick); } //summary at end double avgTime = totalTime.TotalSeconds / testLeaveWin; displayQs(listOfQs); string avgTimes = ""; avgTimes += "The average service time for " + testLeaveWin + " Registrants was " + avgTime + "."; Console.WriteLine(avgTimes); totalTime = new TimeSpan(); Console.WriteLine("fails: " + failDQCounter); Console.WriteLine("leave win:" + testLeaveWin); Console.WriteLine("Patrons: " + counterPatrons); }