static void Calculation(CustomerList customers, TellerList tellers) { Dictionary <string, List <Customer> > customerDict = new Dictionary <string, List <Customer> >(); Dictionary <string, List <Teller> > tellerDict = new Dictionary <string, List <Teller> >(); // Add customers to the customerDict by type foreach (Customer customer in customers.Customer) { // If the dictionary doesn't have the type, create one if (!customerDict.ContainsKey(customer.type)) { customerDict.Add(customer.type, new List <Customer>()); } customerDict[customer.type].Add(customer); } // Add tellers to the tellerDict by specialty type foreach (Teller teller in tellers.Teller) { // If the dictionary doesn't have the type, create one if (!tellerDict.ContainsKey(teller.specialtyType)) { tellerDict.Add(teller.specialtyType, new List <Teller>()); } tellerDict[teller.specialtyType].Add(teller); } double totalDuration = 0; Dictionary <string, double> durationDict = new Dictionary <string, double>(); Dictionary <string, List <Customer> > temporaryCustomerDict = new Dictionary <string, List <Customer> >(customerDict); // Process customers that have the service type matching with one of specialty types foreach (string type in customerDict.Keys) { totalDuration = 0; if (tellerDict.ContainsKey(type)) { // Find the number of customers per teller double customerListLen = customerDict[type].Count; double tellerListLen = tellerDict[type].Count; int customersPerTeller = Convert.ToInt32(Math.Ceiling(customerListLen / tellerListLen)); // We do the following sorting so that customers that have long durations will be assigned to tellers that have small multipliers // Sort the customer list in descending order by duration customerDict[type].Sort((a, b) => Convert.ToDouble(b.duration).CompareTo(Convert.ToDouble(a.duration))); // Sort the teller list in ascending order by multiplier tellerDict[type].Sort((a, b) => Convert.ToDouble(a.multiplier).CompareTo(Convert.ToDouble(b.multiplier))); int count = 1; int tellerIndex = 0; // Appointment creation foreach (Customer customer in customerDict[type]) { // Create a new appointment var appointment = new Appointment(customer, tellerDict[type][tellerIndex]); appointmentList.Add(appointment); // Calculate the total duration for this specialty type double tellerMultiplier = Convert.ToDouble(tellerDict[type][tellerIndex].multiplier); double customerDuration = Convert.ToDouble(customer.duration); totalDuration += tellerMultiplier * customerDuration; // Get the next teller if (count == customersPerTeller) { count = 1; tellerIndex++; } else { count++; } } // Remove assigned customers temporaryCustomerDict.Remove(type); // Update the total duration for this type durationDict.Add(type, totalDuration); } } // Update the dictionary to remove customers that have been assigned customerDict = new Dictionary <string, List <Customer> >(temporaryCustomerDict); // Process customers that do not have a matching type foreach (string customerType in customerDict.Keys) { // Customers will be assigned to the teller group which has the shortest appointment duration // We first sort the list by duration in ascending order and then we get the first element which is the shortest duration var durationList = durationDict.ToList(); durationList.Sort((a, b) => a.Value.CompareTo(b.Value)); string tellerType = durationList[0].Key; double shortestDuration = durationList[0].Value; // Find the number of customers per teller double customerListLen = customerDict[customerType].Count; double tellerListLen = tellerDict[tellerType].Count; int customersPerTeller = Convert.ToInt32(Math.Ceiling(customerListLen / tellerListLen)); int count = 1; int tellerIndex = 0; // Appointment creation foreach (Customer customer in customerDict[customerType]) { // Create a new appointment var appointment = new Appointment(customer, tellerDict[tellerType][tellerIndex]); appointmentList.Add(appointment); // Calculate the total duration for this specialty type shortestDuration += Convert.ToDouble(customer.duration); // Get the next teller if (count == customersPerTeller) { count = 1; tellerIndex++; } else { count++; } } // Update total duration of this specialty type group durationDict[tellerType] = shortestDuration; } }
static void Calculation(CustomerList customers, TellerList tellers) { List <Teller> specialtyOne = new List <Teller>(); List <Teller> specialtyZero = new List <Teller>(); List <Teller> specialtyTwo = new List <Teller>(); List <Teller> specialtyThree = new List <Teller>(); foreach (Teller teller in tellers.Teller) { if (teller.specialtyType == "0") { specialtyZero.Add(teller); } if (teller.specialtyType == "1") { specialtyOne.Add(teller); } if (teller.specialtyType == "2") { specialtyTwo.Add(teller); } if (teller.specialtyType == "3") { specialtyThree.Add(teller); } } /*Console.WriteLine(string.Join("\t", specialtyZero)); * Console.WriteLine(string.Join("\t", specialtyOne)); * Console.WriteLine(string.Join("\t", specialtyTwo)); * Console.WriteLine(string.Join("\t", specialtyThree));*/ // Your code goes here ..... // Re-write this method to be more efficient instead of a random assignment int i = 0; int j = 0; int k = 0; int l = 0; foreach (Customer customer in customers.Customer) { if (customer.type == "4") { var appointmentZero = new Appointment(customer, specialtyZero[i]); appointmentList.Add(appointmentZero); i++; if (i >= specialtyZero.Count) { i = 0; } } if (customer.type == "1") { var appointmentOne = new Appointment(customer, specialtyOne[j]); appointmentList.Add(appointmentOne); j++; if (j >= specialtyOne.Count) { j = 0; } } if (customer.type == "2") { var appointmentTwo = new Appointment(customer, specialtyTwo[k]); appointmentList.Add(appointmentTwo); k++; if (k >= specialtyTwo.Count) { k = 0; } } if (customer.type == "3") { var appointmentThree = new Appointment(customer, specialtyThree[l]); appointmentList.Add(appointmentThree); l++; if (l >= specialtyThree.Count) { l = 0; } } } }
static void Calculation(CustomerList customers, TellerList tellers) { var type1index = 0; var type2index = 0; var type3index = 0; var type4index = 0; //----Start customer order by, We can sort the customers by duration and use if there is no first come first serve //and replace foreach with customersSorted instead of Customers.customer List <Customer> customersSorted = new List <Customer>(); customersSorted = customers.Customer.OrderByDescending(c => c.duration).ToList(); //----End customer order by------------------ foreach (Customer customer in customers.Customer) { // Get tellers by type var tellersByTypeOnly = tellers.TellerByType(customer.type); // ---- Start Prioritize tellers by multiplier, minimum time taken this way by tellers to finish serving customers. var tellersByTypePrioritizedMultiplier = tellersByTypeOnly.OrderByDescending(a => a.multiplier).ToList(); // ---- End Prioritize tellers by multiplier //Console.WriteLine("serving customerId: " + customer.Id + " and Type: " + customer.type); // Take turns with customer appointments Teller servingTeller = new Teller(); if (customer.type == "1") { servingTeller = tellersByTypePrioritizedMultiplier[type1index]; type1index++; if (type1index > tellersByTypePrioritizedMultiplier.Count - 1) { type1index = 0; } } else if (customer.type == "2") { servingTeller = tellersByTypePrioritizedMultiplier[type2index]; type2index++; if (type2index > tellersByTypePrioritizedMultiplier.Count - 1) { type2index = 0; } } else if (customer.type == "3") { servingTeller = tellersByTypePrioritizedMultiplier[type3index]; type3index++; if (type3index > tellersByTypePrioritizedMultiplier.Count - 1) { type3index = 0; } } else if (customer.type == "4") { servingTeller = tellersByTypePrioritizedMultiplier[type4index]; type4index++; if (type4index > tellersByTypePrioritizedMultiplier.Count - 1) { type4index = 0; } } // TODO: prioritize tellers by multiplier Console.WriteLine("teller type:" + servingTeller.specialtyType + " tellerId: " + servingTeller.id); var appointment = new Appointment(customer, servingTeller); appointmentList.Add(appointment); } }
static void Calculation(CustomerList customers, TellerList tellers) { // Your code goes here ..... // Re-write this method to be more efficient instead of a assigning all customers to the same teller //Create a list of al the customer orderby type and the by te longest time IList <Customer> customersSorted = new List <Customer>(); customersSorted = customers.Customer.OrderBy(x => x.type).ThenByDescending(o => o.duration).ToList(); foreach (Customer customer in customersSorted) { IList <Appointment> tellersDuration = new List <Appointment>(); //Create a list of the appointment time of a customer for all tellers foreach (Teller teller in tellers.Teller) { var appointment = new Appointment(customer, teller); tellersDuration.Add(appointment); } var sortedTellers = tellersDuration.OrderBy(o => o.duration).ToList(); //if no appointmet exist yet, add the customer to the quickest teller if (appointmentList.Count == 0) { appointmentList.Add(sortedTellers[0]); } else { for (int i = 0; i < sortedTellers.Count(); i++) { bool containsItem = appointmentList.Any(o => o.teller.id == sortedTellers[i].teller.id); //if the quickest teller doesn't existe yet, we add that appointment if (!containsItem && appointmentList.Count() < sortedTellers.Count()) { appointmentList.Add(sortedTellers[i]); break; } //once i add one customer to all teller we can start adding more custemer to the same tellers else if (containsItem && appointmentList.Count() >= sortedTellers.Count()) { var tellerAppointments = from appointments in appointmentList group appointments by appointments.teller into tellerGroup select new { teller = tellerGroup.Key, totalDuration = tellerGroup.Sum(x => x.duration), }; double totalTime = 0; int tellerIndexAdd = 0; var tellerAppointmentsSorted = tellerAppointments.OrderBy(x => x.totalDuration).ToList(); //iterate through the teller order by the total duration of their appointments for (int j = 0; j < tellerAppointmentsSorted.Count(); j++) { var tellerTotalDurationId = tellerAppointmentsSorted[j].teller.id; int tellerIndex = sortedTellers.FindIndex(a => a.teller.id == tellerTotalDurationId); //if it is the first time in this loop we update the //total time to the total time plus the duration of the new apppoitment //and get that teller index to add the appointment if (totalTime == 0) { totalTime = tellerAppointmentsSorted[j].totalDuration + sortedTellers[tellerIndex].duration; tellerIndexAdd = tellerIndex; } //if the total time plus the new appointment time of the previous teller is higher than the next teller //then we update the total time for the fastest one and get that telle index to add the new appointment else if (totalTime > tellerAppointmentsSorted[j].totalDuration + sortedTellers[tellerIndex].duration) { totalTime = tellerAppointmentsSorted[j].totalDuration + sortedTellers[tellerIndex].duration; tellerIndexAdd = tellerIndex; } } appointmentList.Add(sortedTellers[tellerIndexAdd]); break; } } } } }
static void Calculation(CustomerList customers, TellerList tellers) { // Your code goes here ..... // Re-write this method to be more efficient instead of a random assignment var type0 = new TellerList(); var type1 = new TellerList(); var type2 = new TellerList(); var type3 = new TellerList(); tellers.Teller.ForEach(teller => { var type = teller.specialtyType; if (type == "0") { type0.Teller.Add(teller); } else if (type == "1") { type1.Teller.Add(teller); } else if (type == "2") { type2.Teller.Add(teller); } else if (type == "3") { type3.Teller.Add(teller); } }); var type0Sorted = type0.Teller.OrderBy(x => x.multiplier).ToList(); var type1Sorted = type1.Teller.OrderBy(x => x.multiplier).ToList(); var type2Sorted = type2.Teller.OrderBy(x => x.multiplier).ToList(); var type3Sorted = type3.Teller.OrderBy(x => x.multiplier).ToList(); var cusType0 = new CustomerList(); var cusType1 = new CustomerList(); var cusType2 = new CustomerList(); var cusType3 = new CustomerList(); var cusType4 = new CustomerList(); customers.Customer.ForEach(customer => { var type = customer.type; if (type == "0") { cusType0.Customer.Add(customer); } else if (type == "1") { cusType1.Customer.Add(customer); } else if (type == "2") { cusType2.Customer.Add(customer); } else if (type == "3") { cusType3.Customer.Add(customer); } else { cusType4.Customer.Add(customer); } }); // var cusType0Sorted = cusType0.Customer.OrderByDescending(x => x.duration); var cusType1Sorted = cusType1.Customer.OrderByDescending(x => x.duration).ToList(); var cusType2Sorted = cusType2.Customer.OrderByDescending(x => x.duration).ToList(); var cusType3Sorted = cusType3.Customer.OrderByDescending(x => x.duration).ToList(); var cusType4Sorted = cusType4.Customer.OrderByDescending(x => x.duration).ToList(); AssignApp(cusType4Sorted, type0Sorted); AssignApp(cusType1Sorted, type1Sorted); AssignApp(cusType2Sorted, type2Sorted); AssignApp(cusType3Sorted, type3Sorted); //foreach (Customer customer in customers.Customer) //{ // var appointment = new Appointment(customer, tellers.Teller[random.Next(150)]); // appointmentList.Add(appointment); //} }
static void Calculation(CustomerList customers, TellerList tellers) { List <Teller> tellerSpecZero = new List <Teller>(); List <Teller> tellerSpecOne = new List <Teller>(); List <Teller> tellerSpecTwo = new List <Teller>(); List <Teller> tellerSpecThree = new List <Teller>(); foreach (Teller teller in tellers.Teller) { if (teller.specialtyType == "0") { tellerSpecZero.Add(teller); } if (teller.specialtyType == "1") { tellerSpecOne.Add(teller); } if (teller.specialtyType == "2") { tellerSpecTwo.Add(teller); } if (teller.specialtyType == "3") { tellerSpecThree.Add(teller); } } int i = 0, j = 0, k = 0, l = 0; foreach (Customer customer in customers.Customer) { if (customer.type == "1") { var appointmentOne = new Appointment(customer, tellerSpecOne[j]); appointmentList.Add(appointmentOne); j++; if (j >= tellerSpecOne.Count) { j = 0; } } if (customer.type == "2") { var appointmentTwo = new Appointment(customer, tellerSpecTwo[k]); appointmentList.Add(appointmentTwo); k++; if (k >= tellerSpecTwo.Count) { k = 0; } } if (customer.type == "3") { var appointmentThree = new Appointment(customer, tellerSpecThree[l]); appointmentList.Add(appointmentThree); l++; if (l >= tellerSpecThree.Count) { l = 0; } } if (customer.type == "4") { var appointmentZero = new Appointment(customer, tellerSpecZero[i]); appointmentList.Add(appointmentZero); i++; if (i >= tellerSpecZero.Count) { i = 0; } } } }