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;
        }
Esempio n. 2
0
 public bool Includes(DateRange range)
 {
     return (Start <= range.Start) && (range.End <= End);
 }