private void CheckAdToAdCompatibility(AdvertisementTask other, int otherPosition) { if (_currentAd == other && otherPosition != _currentAdPosition) { _currentAdCount += 1; int distance = Math.Abs(_currentAdPosition - otherPosition); if (distance <= _currentAd.MinJobsBetweenSame) { _currentlyAssessed.SelfSpacingConflicts += 1; } } else { if (other.Type.ID == _currentAd.Type.ID && other.Brand.ID != _currentAd.Brand.ID) { if (_currentAdIncompatibilityCosts != null) { if (_currentAdIncompatibilityCosts.TryGetValue(other.Brand.ID, out double weight)) { _currentlyAssessed.MildIncompatibilitySumOfOccurenceWeights += weight; } else { _currentlyAssessed.OwnerConflicts += 1; } } } } }
private void TryToScheduleOrder(AdvertisementTask order) { foreach (var tvBreak in _breakInOrder) { var schedule = Solution.AdvertisementsScheduledOnBreaks[tvBreak.ID]; if (schedule.UnitFill - MaxBreakExtensionUnits > tvBreak.SpanUnits) { continue; } InsertFactory factory = new InsertFactory(Solution) { Breaks = new[] { tvBreak }, Tasks = new[] { order }, MildlyRandomOrder = false, PositionsCountLimit = PositionsPerBreakTakenIntoConsideration, Random = Random, }; List <ITransformation> moves = factory.GenerateMoves().ToList(); ChooseMoveToPerform(moves); if (TimeLimit < CurrentTime.Elapsed) { break; } } }
private void CalculateAdConstraints(AdvertisementTask order, int position) { _currentAdPosition = position; _currentAdCount = 1; _currentAd = order; if (!_taksAssessments.TryGetValue(order.ID, out TaskScore assesedTask)) { assesedTask = new TaskScore() { AdConstraints = _currentAd, ScoringFunction = ScoringFunction, }; assesedTask.BreaksPositions.Add(_breakData.ID, new SortedSet <int>()); _taksAssessments.Add(order.ID, assesedTask); } assesedTask.BreaksPositions[_breakData.ID].Add(position); _currentlyAssessed = assesedTask; Instance.BrandIncompatibilityCost.TryGetValue(_currentAd.Brand.ID, out var currentAdWeights); _currentAdIncompatibilityCosts = currentAdWeights; UpdateSimpleStatsForCurrentAd(position); for (int i = 0; i < _schedule.Count; i++) { if (i != _currentAdPosition) { CheckAdToAdCompatibility(_schedule.Order[i], i); } } if (_currentAdCount > _currentAd.MaxPerBlock) { _currentlyAssessed.SelfIncompatibilityConflicts += 1; } }
private void GenerateAdOrderData(AdvertisementTask order) { order.Gain = order.AdvertisementInstances.Sum(a => a.Profit); order.DueTime = order.AdvertisementInstances.OrderBy(a => a.EndTime).Last().EndTime + DueTimeOffset; if (RoundDueTimeUpToDays) { order.DueTime = order.DueTime.AddDays(1).Date; } order.MinViewership = order.AdvertisementInstances.Sum(a => a.Viewers) * MinViewsMultiplier; //Ads with same advertisement ID had different spans in real data, we choose the most frequent one here var modeSpanGroup = order.AdvertisementInstances.ToLookup(a => a.SpanUnits).OrderBy(cat => cat.Count()).Last(); order.AdSpan = modeSpanGroup.First().Span; order.AdSpanUnits = modeSpanGroup.First().SpanUnits; //As a consequence we count the times aired requirements based on total span and above chosen single ad span CountMinTimesAired(order); int minBeginingsCount = order.AdvertisementInstances.Where(a => a.Break.Advertisements.First() == a).Count(); order.MinBeginingsProportion = Math.Max(0, minBeginingsCount + MinBeginingsOffset); order.MinBeginingsProportion /= order.AdvertisementInstances.Count(); order.MinBeginingsProportion *= MinBeginingsMultiplier; int minEndsCount = order.AdvertisementInstances.Where(a => a.Break.Advertisements.Last() == a).Count(); order.MinEndsProportion = Math.Max(0, minEndsCount + MinEndsOffset); order.MinEndsProportion /= order.AdvertisementInstances.Count(); order.MinEndsProportion *= MinEndsMultiplier; order.Type = order.AdvertisementInstances.First().Type; order.Brand = order.AdvertisementInstances.First().Brand; GenerateSelfIncompatibilityData(order); order.OverdueCostParameter = order.Gain; }
private void GenerateSelfIncompatibilityData(AdvertisementTask order) { int minSelfInterval = DefaultAdsInBetweenSame; int maxAiredInBlock = 0; foreach (var ad in order.AdvertisementInstances) { var adsInThisBreak = ad.Break.Advertisements; int indexStarting = adsInThisBreak.IndexOf(ad); int times = 1; for (int i = indexStarting + 1; i < adsInThisBreak.Count; i++) { if (adsInThisBreak[i].AdvertisementOrder.ID == order.ID) { times += 1; if (minSelfInterval > i - indexStarting - 1) { minSelfInterval = i - indexStarting - 1; } } } if (maxAiredInBlock < times) { maxAiredInBlock = times; } } order.MinJobsBetweenSame = Math.Max(minSelfInterval + MinAdsInBetweenSameOffset, 0); order.MaxPerBlock = Math.Max(maxAiredInBlock + MaxAdsPerBreakOffset, 1); }
public void Insert(int position, AdvertisementTask ad) { _order.Insert(position, ad); int previousEnd = position - 1 >= 0 ? _endTimes[position - 1] : 0; _endTimes.Insert(position, previousEnd + ad.AdSpanUnits); for (int i = position + 1; i < _endTimes.Count; i++) { _endTimes[i] += ad.AdSpanUnits; } }
private void CountMinTimesAired(AdvertisementTask order) { TimeSpan sumSpan = new TimeSpan(0, 0, 0); foreach (AdvertisementInstance ad in order.AdvertisementInstances) { sumSpan += ad.Span; } int requiredAmount = order.AdvertisementInstances.Count; if (MinTimesAiredWeighted) { requiredAmount = (int)(sumSpan.TotalMilliseconds / order.AdSpan.TotalMilliseconds); } order.MinTimesAired = Math.Max(Convert.ToInt32(Math.Max(requiredAmount + MinTimesAiredOffset, 0) * MinTimesAiredMultiplier), 1); }
public void AddAd(AdvertisementTask ad) { _order.Add(ad); _endTimes.Add(_endTimes.LastOrDefault() + ad.AdSpanUnits); }