public bool Calculate(FitnessRequest request) { //Todo //Change this so each chromosome is converted into a List<Slot> so LINQ can be used. Not getting correct shedule when choose selected events. for (int popIdx = 0; popIdx < request.Population.Count(); popIdx++) { //Process chromosome. List<string> genes = Helpers.SplitIntoChunks(request.Population[popIdx].ScheduleString, request.GeneLength).ToList<string>(); List<TimeSlot> chromosomeSlots = Helpers.GetSlots(genes, request.TimeSlots); DateRange defaultDateRange = new DateRange(new DateTime(1000, 1, 1, 00, 00, 00), new DateTime(9999, 12, 31, 23, 59, 59)); List<TimeSlot> filteredSlots = chromosomeSlots .Where(slot => request.SelectedDateRanges.DefaultIfEmpty(defaultDateRange). Any(dateRange => dateRange.Start < slot.EndTime && dateRange.End > slot.StartTime)).ToList<TimeSlot>(); //Dedupe duplicate slots List<TimeSlot> dedupedSlots = new List<TimeSlot>(); foreach (TimeSlot slot in filteredSlots) { if (!dedupedSlots.Contains(slot)) { dedupedSlots.Add(slot); } } ////Selected events are messing this up. It works when there's selected dates //or no selected dates, but not with selected events. For some reason, //only a few events around the selected events are included, like 2 //either side. Something about selected events breaks the clash code. ////After the loop above, all slots not in selected date range have been filtered out. // //Now we can go through those and see which ones contain selected events. foreach (TimeSlot slot in dedupedSlots) { if (request.SelectedFilms.Count == 0) { break; } if (SlotHasSelectedEvent(request, slot, popIdx)) { slot.Selected = true; request.Population[popIdx].Fitness++; request.Population[popIdx].UniqueSlots.Add(slot); request.Population[popIdx].UniqueEvents.Add(slot.Event.ID); } } //if (request.Population[popIdx].Fitness < request.SelectedEvents.Count) //{ // request.Population[popIdx].Fitness = 0; // request.Population[popIdx].UniqueSlots.Clear(); // request.Population[popIdx].UniqueEvents.Clear(); // continue; //} List<TimeSlot> sortedSlots = dedupedSlots.OrderBy(o => o.StartTime).ToList(); //Now we've got all the slots with selected events marked as Selected. They're fixed now. //If we want more than just the selected events, get the remaining unselected slots that don't clash //with any other currently unselected slot. if (request.SelectedFilmsOnly == false) { // foreach (Slot slot in filteredSlots.Where(s => s.Selected == false)) for (int i = 0; i < sortedSlots.Count; i++) { TimeSlot slot = sortedSlots[i]; if (slot.Selected) { continue; } bool fits = true; // foreach (Slot sibling in filteredSlots.Where(sib => sib.ID != slot.ID)) for (int j = i + 1; j < sortedSlots.Count; j++) { //Don't compare same slot. // if (j == i) { continue; } TimeSlot sibling = sortedSlots[j]; //if (sibling.Selected) //{ // continue; //} //if ((sibling.ID == 74 & slot.ID == 113) || (sibling.ID == 113 & slot.ID == 74)) //{ // break; //} int addedTime = CalculateAddedTime(request, slot, sibling); DateTime slotAmendedStart = slot.StartTime.AddMinutes(addedTime * -1); DateTime slotAmendedEnd = slot.EndTime.AddMinutes(addedTime); fits = !(slotAmendedStart < sibling.EndTime && slotAmendedEnd > sibling.StartTime); if (!fits) { break; } //113 louis 74 other //Do we allow duplicate event IDs? fits = ((request.AllowDuplicateEvents) || (request.AllowDuplicateEvents == false && slot.Event.ID != sibling.Event.ID)); if (!fits) { break; } } // } if (fits) { slot.Selected = true; request.Population[popIdx].Fitness++; request.Population[popIdx].UniqueSlots.Add(slot); request.Population[popIdx].UniqueEvents.Add(slot.Event.ID); } } } } return true; }
public bool Includes(DateRange range) { return (Start <= range.Start) && (range.End <= End); }