void Start() { var tableIndices = Enumerable.Range(0, Config.NDiningTables).Where(i => DiningTables[i].Count == 0).ToList(); if (tableIndices.Count > 0 && Waiting.Count > 0) { var tblIdx = tableIndices.First(); /// get the table List <int> indices = null; var sizes = Waiting.Select(g => g.Count).ToList(); switch (Config.BatchingRule) { case Statics.BatchingRules.None: indices = new List <int> { 0 }; break; case Statics.BatchingRules.Table8: indices = Batch(sizes, 8, 8); break; case Statics.BatchingRules.Table4: indices = Batch(sizes, 8, 8); if (indices == null) { indices = Batch(sizes, 4, 4); } break; case Statics.BatchingRules.Table4to8: indices = Batch(sizes, 4, 8); break; } /// Start dining if (indices != null) { /// assign from bar seat to dining table DiningTables[tblIdx] = indices.SelectMany(i => Waiting[i]).ToList(); HourCounterDinnersServing.ObserveChange(DiningTables[tblIdx].Count, ClockTime); HourCounterTablesServing.ObserveChange(1, ClockTime); foreach (var c in DiningTables[tblIdx]) { c.DiningTime = ClockTime; c.TableIndex = tblIdx; if (c.BarSeatIndex > -1) { BarSeats[c.BarSeatIndex] = null; HourCounterCustomersInBar.ObserveChange(-1, ClockTime); } // count drinks var waitingHours = (c.DiningTime - c.ArrivalTime).TotalHours; if (waitingHours > 0) { var nDrinks = MathNet.Numerics.Distributions.Poisson.Sample(DefaultRS, Config.ExpectedNDrinksPerHour * waitingHours); if (c.ArrivalTime.Hour < Config.PeakStartingHour && Config.AdsOption == Statics.AdsOptions.HappyHour) { TotalNDrinksServedInHappyHours += nDrinks; } TotalNDrinksServed += nDrinks; } } Waiting = Enumerable.Range(0, Waiting.Count).Where(i => !indices.Contains(i)).Select(i => Waiting[i]).ToList(); /// dining time var mean = Config.ExpectedDiningMinutesduringPeak; if (ClockTime.Hour < Config.PeakStartingHour) { mean = Config.ExpectedDiningMinutesbeforePeak; } if (ClockTime.Hour >= Config.PeakEndingHour) { mean = Config.ExpectedDiningMinutesafterPeak; } Schedule(() => Depart(tblIdx), TimeSpan.FromMinutes(Exponential.Sample(DefaultRS, mean))); } } /// Reject non-seated customers, if capacity limit is exceeded if (Waiting.Sum(g => g.Count) > Config.NBarSeats) { Reject(Waiting.Last()); Waiting.RemoveAt(Waiting.Count - 1); } /// Seat newly arrived customers int barSeatIdx = 0; foreach (var c in Waiting.SelectMany(g => g).Where(c => c.BarSeatIndex < 0).ToList()) { while (BarSeats[barSeatIdx] != null) { barSeatIdx++; } c.BarSeatIndex = barSeatIdx; BarSeats[barSeatIdx] = c; HourCounterCustomersInBar.ObserveChange(1, ClockTime); } Result.Update(this, ClockTime); }