private bool SlotHasSelectedEvent(FitnessRequest request, TimeSlot slot, int popIdx)
        {
            if (request.SelectedFilms.Count == 0) { return false; }
            //Is the event in this slot one of the selected events?
            if ((request.SelectedFilms.Count > 0) && ((request.SelectedFilms.Any(e => e.Value.ID == slot.Event.ID)) == false))
            {
                //Event isn't one of the selected events.
                return false;
            }
            else
            {
                //Has the event already been added?
                if (request.Population[popIdx].UniqueEvents.Any(e => e == slot.Event.ID))
                {
                    return false;
                }
                else
                {
                    return true;
                }

            }
        }
 private bool SlotInSelectedDateRanges(FitnessRequest request, TimeSlot slot)
 {
     //Is this slot within any of the selected date ranges?
     if ((request.SelectedDateRanges.Count > 0) &&
         ((request.SelectedDateRanges.Any(s => s.Start < slot.EndTime && s.End > slot.StartTime)) == false))
     {
         //If there are selected date ranges and the current slot doesn't occur within it, move on to the next gene.
         return false;
     }
     else
     {
         return true;
     }
 }
        //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].ChromosomeString, request.GeneLength).ToList<string>();
        //        List<Slot> chromosomeSlots = Helpers.GetSlots(genes, request.Slots);
        //        DateRange defaultDateRange = new DateRange(new DateTime(1000, 1, 1, 00, 00, 00), new DateTime(9999, 12, 31, 23, 59, 59));
        //        List<Slot> filteredSlots = chromosomeSlots
        //            .Where(slot =>
        //            request.SelectedDateRanges.DefaultIfEmpty(defaultDateRange).
        //            Any(dateRange => dateRange.Start < slot.EndTime && dateRange.End > slot.StartTime)).ToList<Slot>();
        //        //Dedupe duplicate slots
        //        List<Slot> dedupedSlots = new List<Slot>();
        //        foreach (Slot 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 (Slot slot in dedupedSlots)
        //        {
        //            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<Slot> 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.SelectedEventsOnly == false)
        //        {
        //           // foreach (Slot slot in filteredSlots.Where(s => s.Selected == false))
        //            for (int i = 0; i < sortedSlots.Count; i++)
        //            {
        //                Slot 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; }
        //                    Slot 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);
        //                }
        //            }
        //        }
        //        //    // if (!SlotInSelectedEvents(request, slot)) { continue; }
        //        //    if (SlotHasSelectedEvent(request, slot))
        //        //    {
        //        //        if (request.Population[popIdx].UniqueEvents.Any(l => l == slot.Event.ID) == false)
        //        //        {
        //        //            request.Population[popIdx].Fitness++;
        //        //            request.Population[popIdx].UniqueSlots.Add(slot.ID);
        //        //            request.Population[popIdx].UniqueEvents.Add(slot.Event.ID);
        //        //            continue;
        //        //        }
        //        //    }
        //        //    else
        //        //    {
        //        //        if (request.SelectedEvents.Count > 0 && request.SelectedEventsOnly == false
        //        //            && SlotFitsInSchedule(request, genes, i, slot) && (request.Population[popIdx].UniqueEvents.Any(l => l == slot.Event.ID) == false))
        //        //        {
        //        //            request.Population[popIdx].Fitness++;
        //        //            request.Population[popIdx].UniqueSlots.Add(slot.ID);
        //        //            request.Population[popIdx].UniqueEvents.Add(slot.Event.ID);
        //        //            continue;
        //        //        }
        //        //    }
        //        //}
        //    //    DateRange defaultDateRange = new DateRange(new DateTime(9999, 12, 31, 23, 59, 59), new DateTime(1000, 1, 1, 00, 00, 00));
        //    //   // List<Slot> filteredSlots = chromosomeSlots.Where(f =>
        //    //    //   request.SelectedDateRanges.DefaultIfEmpty(defaultDateRange).
        //    //    //    Any(s =>s.Start < f.EndTime && s.End > f.StartTime) == false).ToList<Slot>();
        //    //        //  if ((request.SelectedDateRanges.Count > 0) &&
        //    //    //((request.SelectedDateRanges.Any(s => s.Start < slot.EndTime && s.End > slot.StartTime)) == false))
        //    //    //Process a gene within chromosome.
        //    //    for (int geneIdx = 0; geneIdx < genes.Count(); geneIdx++)
        //    //    {
        //    //        slotIdx = Convert.ToInt32(genes[geneIdx], 2);
        //    //        //If slot index is higher than number of slots, skip it and move on to next gene.
        //    //        if (slotIdx > request.Slots.Count - 1) { continue; }
        //    //        Slot slot = request.Slots[slotIdx];
        //    //        if (!SlotInSelectedDateRanges(request, slot))
        //    //        {
        //    //            continue;
        //    //        }
        //    //        // if (!SlotInSelectedEvents(request, slot)) { continue; }
        //    //        if (SlotHasSelectedEvent(request, slot))
        //    //        {
        //    //            if (request.Population[popIdx].UniqueEvents.Any(l => l == slot.Event.ID) == false)
        //    //            {
        //    //                request.Population[popIdx].Fitness++;
        //    //                request.Population[popIdx].UniqueSlots.Add(slotIdx);
        //    //                request.Population[popIdx].UniqueEvents.Add(slot.Event.ID);
        //    //                continue;
        //    //            }
        //    //        }
        //    //        else
        //    //        {
        //    //            if (request.SelectedEvents.Count > 0 && request.SelectedEventsOnly == false
        //    //                && SlotFitsInSchedule(request, genes, geneIdx, slot) && (request.Population[popIdx].UniqueEvents.Any(l => l == slot.Event.ID) == false))
        //    //            {
        //    //                request.Population[popIdx].Fitness++;
        //    //                request.Population[popIdx].UniqueSlots.Add(slotIdx);
        //    //                request.Population[popIdx].UniqueEvents.Add(slot.Event.ID);
        //    //                continue;
        //    //            }
        //    //        }
        //    //    }
        //        //int slotIdx = 0;
        //        ////Process a gene within chromosome.
        //        //for (int geneIdx = 0; geneIdx < genes.Count(); geneIdx++)
        //        //{
        //        //    slotIdx = Convert.ToInt32(genes[geneIdx], 2);
        //        //    //If slot index is higher than number of slots, skip it and move on to next gene.
        //        //    if (slotIdx > request.Slots.Count - 1) { continue; }
        //        //    Slot slot = request.Slots[slotIdx];
        //        //    if (!SlotInSelectedDateRanges(request, slot))
        //        //    {
        //        //        continue;
        //        //    }
        //        //   // if (!SlotInSelectedEvents(request, slot)) { continue; }
        //        //    if (SlotHasSelectedEvent(request, slot))
        //        //    {
        //        //        if (request.Population[popIdx].UniqueEvents.Any(l => l == slot.Event.ID) == false)
        //        //        {
        //        //            request.Population[popIdx].Fitness++;
        //        //            request.Population[popIdx].UniqueSlots.Add(slotIdx);
        //        //            request.Population[popIdx].UniqueEvents.Add(slot.Event.ID);
        //        //            continue;
        //        //        }
        //        //    }
        //        //    else
        //        //    {
        //        //        if (request.SelectedEvents.Count > 0 && request.SelectedEventsOnly == false
        //        //            && SlotFitsInSchedule(request, genes, geneIdx, slot) && (request.Population[popIdx].UniqueEvents.Any(l => l == slot.Event.ID) == false))
        //        //        {
        //        //            request.Population[popIdx].Fitness++;
        //        //            request.Population[popIdx].UniqueSlots.Add(slotIdx);
        //        //            request.Population[popIdx].UniqueEvents.Add(slot.Event.ID);
        //        //            continue;
        //        //        }
        //        //    }
        //        //}
        //    }
        //    return true;
        //}
        //private bool SlotFitsInSchedule(FitnessRequest request, List<string> genes, int geneIdx, Slot slot)
        //{
        //    bool fits = true;
        //    //Does this slot fit with all the other slots in the chromosome?
        //    for (int siblingGeneIdx = geneIdx + 1; siblingGeneIdx < genes.Count; siblingGeneIdx++)
        //    {
        //        int siblingSlotIdx = Convert.ToInt32(genes[siblingGeneIdx], 2);
        //        //If the slot index is higher than total number of slots, treat it as a
        //        //blank slot and say it doesn't fit. It's only fits that increase
        //        //fitness, so if blanks are seen as fit, we get an empty schedule full of
        //        //blank slots.
        //        if (siblingSlotIdx > request.Slots.Count - 1)
        //        {
        //            continue;
        //        }
        //        Slot siblingSlot = request.Slots[siblingSlotIdx];
        //        if (SlotHasSelectedEvent(request, siblingSlot))
        //        {
        //            fits = false;
        //            break;
        //        }
        //        //if (!SlotInSelectedDateRanges(request, siblingSlot)) { continue; }
        //        int addedTime = CalculateAddedTime(request, slot, siblingSlot);
        //        DateTime slotAmendedStart = slot.StartTime.AddMinutes(addedTime * -1);
        //        DateTime slotAmendedEnd = slot.EndTime.AddMinutes(addedTime);
        //        //Fits if slot doesn't clash and the slot events are different
        //        fits = !(slotAmendedStart < siblingSlot.EndTime && slotAmendedEnd > siblingSlot.StartTime);
        //        if (!fits) { break; }
        //        //Do we allow duplicate event IDs?
        //        fits = ((request.AllowDuplicateEvents) || (request.AllowDuplicateEvents == false && slot.Event.ID != siblingSlot.Event.ID));
        //        if (!fits) { break; }
        //    }
        //    return fits;
        //}
        //private bool SlotFitsInSchedule2(FitnessRequest request, List<string> genes, int geneIdx, Slot slot)
        //{
        //    bool fits = true;
        //    //Does this slot fit with all the other slots in the chromosome?
        //    for (int siblingGeneIdx = geneIdx + 1; siblingGeneIdx < genes.Count; siblingGeneIdx++)
        //    {
        //        int siblingSlotIdx = Convert.ToInt32(genes[siblingGeneIdx], 2);
        //        //If the slot index is higher than total number of slots, treat it as a
        //        //blank slot and say it doesn't fit. It's only fits that increase
        //        //fitness, so if blanks are seen as fit, we get an empty schedule full of
        //        //blank slots.
        //        if (siblingSlotIdx > request.Slots.Count - 1)
        //        {
        //            continue;
        //        }
        //        Slot siblingSlot = request.Slots[siblingSlotIdx];
        //        if (SlotHasSelectedEvent(request, siblingSlot))
        //        {
        //            fits = false;
        //            break;
        //        }
        //        //if (!SlotInSelectedDateRanges(request, siblingSlot)) { continue; }
        //        int addedTime = CalculateAddedTime(request, slot, siblingSlot);
        //        DateTime slotAmendedStart = slot.StartTime.AddMinutes(addedTime * -1);
        //        DateTime slotAmendedEnd = slot.EndTime.AddMinutes(addedTime);
        //        //Fits if slot doesn't clash and the slot events are different
        //        fits = !(slotAmendedStart < siblingSlot.EndTime && slotAmendedEnd > siblingSlot.StartTime);
        //        if (!fits) { break; }
        //        //Do we allow duplicate event IDs?
        //        fits = ((request.AllowDuplicateEvents) || (request.AllowDuplicateEvents == false && slot.Event.ID != siblingSlot.Event.ID));
        //        if (!fits) { break; }
        //    }
        //    return fits;
        //}
        private static int CalculateAddedTime(FitnessRequest request, TimeSlot slot, TimeSlot siblingSlot)
        {
            int addedTime = 0;

            if (slot.Venue != siblingSlot.Venue)
            {
                Dictionary<GeneticAlgorithm.Scheduler.EnumVenues, TravelTime> travelTimesForVenue = request.TravelTimes[slot.Venue];
                TravelTime travelTimesToDestination = travelTimesForVenue[siblingSlot.Venue];

                //Factor in travel times.
                switch (request.PreferredTravelOption)
                {
                    case GeneticAlgorithm.Scheduler.EnumTravelOptions.OnFoot:
                        addedTime = travelTimesToDestination.OnFoot;
                        break;
                    case GeneticAlgorithm.Scheduler.EnumTravelOptions.ByCar:
                        addedTime = travelTimesToDestination.ByCar;
                        break;
                    default:
                        break;
                }
            }

            addedTime += request.ContingencyMins;
            addedTime += request.GapBetweenTimeSlotsMins;

            return addedTime;
        }
        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. 5
0
 private string CreateReplacementGenes(FitnessRequest request)
 {
     string replacementGenes = string.Empty;
     foreach (int slotIdx in request.TimeSlotsWithSelectedFilms)
     {
         replacementGenes += Helpers.ConvertIntToBinaryString(slotIdx, request.GeneLength);
     }
     return replacementGenes;
 }
Esempio n. 6
0
 private void PreloadTimeSlotsWithSelectedFilms(FitnessRequest request)
 {
     if (request.ReplacementGenes.Length == 0) { return; }
     int replacementLength = request.ReplacementGenes.Length;
     foreach (Schedule schedule in request.Population)
     {
         //Starting at the start of each schedule, overwrite with slots containing selected events
         string rewrittenSchedule = request.ReplacementGenes + schedule.ScheduleString.Substring(replacementLength);
         schedule.ScheduleString = rewrittenSchedule;
     }
 }
Esempio n. 7
0
        private FitnessRequest InitialiseData(DataTable eventData, DataTable travelTimeData)
        {
            //Get initial data
            FitnessRequest retVal = new FitnessRequest();

            // Films and TimeSlots never change once set.
            retVal.Films = PopulateFilms(eventData);
            retVal.TimeSlots = PopulateTimeSlots(eventData, retVal.Films);
            retVal.TimeSlots = retVal.TimeSlots.OrderBy(o => o.StartTime).ToList();
            retVal.GeneLength = Helpers.ConvertIntToBinaryString(retVal.TimeSlots.Count).Length;

            // A population is a list of alternative schedules. A schedule is a list of index numbers from the TimeSlots lost, expresesed in binary in a long string.
            retVal.Population = PopulateSchedules(retVal.TimeSlots.Count, retVal.GeneLength);

            //Get default user options
            retVal.SelectedFilms = PopulateDefaultSelectedFilms(retVal.Films);
            retVal.SelectedDateRanges = PopulateDefaultSelectedDateRanges(retVal.TimeSlots);
            retVal.TravelTimes = PopulateDefaultTravelTimes(travelTimeData);
            retVal.PreferredTravelOption = _defaultPreferredTravelOption;
            retVal.ContingencyMins = _defaultContingencyMins;
            retVal.GapBetweenTimeSlotsMins = _defaultGapBetweenSlotsMins;
            retVal.AllowDuplicateEvents = _defaultAllowDuplicateEvents;
            retVal.SelectedFilmsOnly = _defaultSelectedEventsOnly;
            retVal.TimeSlotsWithSelectedFilms = PopulateTimeSlotsWithSelectedFilms(retVal.SelectedFilms, retVal.TimeSlots);
            retVal.ReplacementGenes = CreateReplacementGenes(retVal);

            return retVal;
        }