private void CreateSchedule(BreakSchedule schedule) { var advertisementDataList = Solution.AdOrdersScores.Values.Where(t => !t.TimesAiredSatisfied || t.ViewsSatisfied).ToList(); advertisementDataList.Shuffle(Random); foreach (var ad in advertisementDataList) { if (Instance.GetTypeToBreakIncompatibility(ad, schedule) == 1) { continue; } if (Instance.GetBulkBrandIncompatibilities(ad.AdConstraints, schedule.Order).Contains(double.PositiveInfinity)) { continue; } schedule.AddAd(ad.AdConstraints); if (schedule.UnitFill > schedule.BreakData.SpanUnits + MaxOverfillUnits) { break; } } ScoringFunction.AssesBreak(schedule); AddToSolutionScores(schedule.Scores); GenerateReportEntry(); }
private bool InsertInRandomNonFilledBreak(TaskScore taskData) { List <BreakSchedule> breaksWithEnoughSpace = Solution.AdvertisementsScheduledOnBreaks.Values.Where ( b => b.BreakData.SpanUnits >= b.UnitFill + taskData.AdConstraints.AdSpanUnits ).ToList(); if (breaksWithEnoughSpace.Count == 0) { return(false); } int breakNum = Random.Next(breaksWithEnoughSpace.Count); BreakSchedule schedule = breaksWithEnoughSpace[breakNum]; int position = Random.Next(schedule.Count + 1); Insert insert = new Insert() { TvBreak = schedule.BreakData, AdvertisementOrder = taskData.AdConstraints, Position = position, Instance = Instance, Solution = Solution, }; insert.Asses(); insert.Execute(); Reporter.AddEntry(insert.GenerateReportEntry()); return(true); }
public IEnumerable <Insert> GenerateInsertMoves() { int movesReturned = 0; PrepareStructures(); foreach (var tvBreak in _breaks) { BreakSchedule schedule = Solution.AdvertisementsScheduledOnBreaks[tvBreak.ID]; foreach (var task in _tasks) { var positionList = GeneratePossiblePositions(schedule); foreach (int position in positionList) { movesReturned += 1; yield return(new Insert() { Solution = Solution, Instance = Instance, Position = position, AdvertisementOrder = task, TvBreak = tvBreak }); if (movesReturned > MaxMovesReturned) { yield break; } } } } }
private void TryToCleanBreak(BreakSchedule tvBreak) { for (int pos = tvBreak.Count - 1; pos >= 0; --pos) { if (DeleteOnlyOverfull && tvBreak.UnitFill <= tvBreak.BreakData.SpanUnits) { break; } Delete delete = new Delete() { Solution = Solution, TvBreak = tvBreak.BreakData, Position = pos, }; delete.Asses(); if (delete.OverallDifference.HasScoreImproved() && !delete.OverallDifference.AnyCompatibilityIssuesIncreased()) { delete.Execute(); Reporter.AddEntry(delete.GenerateReportEntry()); _numberOfMoves += 1; _movePerformed = true; } if (CurrentTime.Elapsed >= TimeLimit) { break; } } }
private List<int> GetPossibleInserts(TaskScore taskScore, BreakSchedule breakSchedule) { List<int> added = new List<int>(); if(!taskScore.BreaksPositions.TryGetValue(breakSchedule.ID, out var breakPositions)) { breakPositions = new SortedSet<int>(); } //make it a list copy var positionsList = breakPositions.ToList(); int arrIndex = 0; for(int possiblePos = 0; possiblePos < breakSchedule.Order.Count + 1; ) { if (added.Count >= MaxInsertedPerBreak) break; if (breakPositions.Count >= taskScore.AdConstraints.MaxPerBlock) break; if (breakSchedule.UnitFill + (added.Count + 1) * taskScore.AdConstraints.AdSpanUnits > breakSchedule.BreakData.SpanUnits + MaxBreakExtensionUnits) break; int nextPos = breakPositions.Count > arrIndex ? positionsList[arrIndex] : 999999999; if (possiblePos + taskScore.AdConstraints.MinJobsBetweenSame <= nextPos) { added.Add(possiblePos); for(int j = arrIndex; j < breakPositions.Count; j++) { positionsList[j] += 1; } positionsList.Insert(arrIndex, possiblePos); possiblePos += taskScore.AdConstraints.MinJobsBetweenSame + 1; } else { possiblePos = nextPos + taskScore.AdConstraints.MinJobsBetweenSame + 1; } arrIndex += 1; } return added; }
private void ChooseMoveToPerform(List<int> positions, TaskScore taskScore, BreakSchedule breakSchedule) { foreach(var position in positions) { Insert move = new Insert() { Solution = Solution, Position = position, TvBreak = breakSchedule.BreakData, AdvertisementOrder = taskScore.AdConstraints, }; move.Asses(); if(move.OverallDifference.HasScoreImproved() && !move.OverallDifference.AnyCompatibilityIssuesIncreased()) { move.Execute(); Reporter.AddEntry(move.GenerateReportEntry()); _numberOfMoves += 1; _movePerformed = true; } else { break; } if (CurrentTime.Elapsed >= TimeLimit) break; } }
public void CleanData() { _changedOrderStatsAfter = null; _oldBreakScores = null; _newBreakScores = null; _oldSchedule = null; _newSchedule = null; CompletionDifferences = null; }
public IEnumerable <Swap> GenerateSwapMoves() { int movesReturned = 0; PrepareStructures(); foreach (var tvBreak in _breaks) { BreakSchedule schedule = Solution.AdvertisementsScheduledOnBreaks[tvBreak.ID]; foreach (var task in _tasks) { IEnumerable <int> positionList = Enumerable.Range(0, schedule.Count); if (MildlyRandomOrder) { positionList = positionList.ToList(); (positionList as IList <int>).Shuffle(Random); } if (PositionsCountLimit != 0) { if (AlwaysReturnStartsAndEnds) { if (positionList.Count() > 2) { var newList = new List <int> { positionList.First(), positionList.Last() }; newList.AddRange(positionList.Take(PositionsCountLimit - 2)); positionList = newList; } } else { positionList = positionList.Take(PositionsCountLimit); } } foreach (int position in positionList) { movesReturned += 1; yield return(new Swap() { Solution = Solution, Instance = Instance, Position = position, AdvertisementOrder = task, TvBreak = tvBreak }); if (movesReturned > MaxMovesReturned) { yield break; } } } } }
public void AssesBreak(BreakSchedule schedule) { _schedule = schedule; _breakData = schedule.BreakData; _taksAssessments = new Dictionary <int, TaskScore>(); _unitsFromStart = 0; for (int i = 0; i < _schedule.Count; i++) { CalculateAdConstraints(_schedule.Order[i], i); _unitsFromStart += _currentAd.AdSpanUnits; } schedule.Scores = _taksAssessments; }
private void CountBreakTaskChanges() { _oldSchedule = Solution.AdvertisementsScheduledOnBreaks[TvBreak.ID]; if (_oldSchedule.Scores == null) { Solution.GradingFunction.AssesBreak(_oldSchedule); } _oldBreakScores = _oldSchedule.Scores.ToDictionary(s => s.Key, s => s.Value); _newSchedule = _oldSchedule.DeepClone(); _newSchedule.Insert(Position, AdvertisementOrder); Solution.GradingFunction.AssesBreak(_newSchedule); _newBreakScores = _newSchedule.Scores.ToDictionary(s => s.Key, s => s.Value); }
private void PerformIfTransformationImprovesScore(TaskScore taskScore, BreakSchedule breakSchedule) { Insert move = new Insert() { Solution = Solution, Position = breakSchedule.Count, TvBreak = breakSchedule.BreakData, AdvertisementOrder = taskScore.AdConstraints, }; move.Asses(); if (move.OverallDifference.HasScoreImproved() && !move.OverallDifference.AnyCompatibilityIssuesIncreased()) { move.Execute(); Reporter.AddEntry(move.GenerateReportEntry()); _numberOfMoves += 1; _movePerformed = true; } }
private void InsertInRandomBreak(TaskScore taskData) { int breakNum = Random.Next(Instance.Breaks.Count); TvBreak tvBreak = Instance.Breaks.Values.ToList()[breakNum]; BreakSchedule schedule = Solution.AdvertisementsScheduledOnBreaks[tvBreak.ID]; int position = Random.Next(schedule.Count + 1); Insert insert = new Insert() { TvBreak = schedule.BreakData, AdvertisementOrder = taskData.AdConstraints, Position = position, Instance = Instance, Solution = Solution, }; insert.Asses(); insert.Execute(); Reporter.AddEntry(insert.GenerateReportEntry()); }
private bool CheckForNoSelfConflicts(TaskScore taskScore, BreakSchedule breakSchedule) { if (!taskScore.BreaksPositions.TryGetValue(breakSchedule.ID, out var breakPositions)) { breakPositions = new SortedSet <int>(); } if (breakPositions.Count >= taskScore.AdConstraints.MaxPerBlock) { return(false); } if (breakSchedule.UnitFill + taskScore.AdConstraints.AdSpanUnits > breakSchedule.BreakData.SpanUnits + MaxBreakExtensionUnits) { return(false); } int lastPos = breakPositions.Count > 0 ? breakPositions.Last() : 999999999; if (Math.Abs(lastPos - breakSchedule.Count) < taskScore.AdConstraints.MinJobsBetweenSame) { return(false); } return(true); }
private List <int> GeneratePossiblePositions(BreakSchedule schedule) { IEnumerable <int> positionList = null; if (PositionsCountLimit == 0 || !AlwaysReturnStartsAndEnds) { positionList = Enumerable.Range(0, schedule.Count + 1); } else { positionList = Enumerable.Range(1, schedule.Count); } if (MildlyRandomOrder) { positionList = positionList.ToList(); (positionList as IList <int>).Shuffle(Random); } if (PositionsCountLimit != 0) { if (AlwaysReturnStartsAndEnds) { if (positionList.Count() >= 2) { var newList = new List <int> { positionList.First(), positionList.Last() }; newList.AddRange(positionList.Take(PositionsCountLimit - 2)); positionList = newList; } } else { positionList = positionList.Take(PositionsCountLimit); } } return(positionList.ToList()); }