示例#1
0
        /// <summary>Unplaces the restricted spot.</summary>
        /// <param name="smoothPass">The smooth pass.</param>
        /// <param name="smoothSpot">The smooth spot.</param>
        /// <param name="smoothBreak">The smooth break.</param>
        /// <param name="spotActionMessage">The spot action message.</param>
        /// <param name="spotIdsUsed">The spot ids used.</param>
        private void UnplaceRestrictedSpot(
            SmoothPass smoothPass,
            SmoothSpot smoothSpot,
            SmoothBreak smoothBreak,
            string spotActionMessage,
            ISet <Guid> spotIdsUsed)
        {
            RaiseInfo(
                $"Unplacing booked spot {smoothSpot.Spot.ExternalSpotRef} " +
                $"from break {smoothBreak.TheBreak.ExternalBreakRef}: {spotActionMessage}"
                );

            SpotPlacementService.RemoveSpotFromBreak(
                smoothBreak,
                smoothSpot.Spot,
                spotIdsUsed,
                _sponsorshipRestrictionService
                );

            smoothSpot.IsCurrent = true;

            _smoothDiagnostics.LogSpotAction(
                smoothPass,
                0,
                smoothSpot.Spot,
                smoothBreak,
                SmoothSpot.SmoothSpotActions.RemoveSpotFromBreak,
                spotActionMessage);
        }
示例#2
0
        public void LogBestBreakFactorMessage(
            SmoothPass smoothPass,
            SmoothPassDefaultIteration smoothPassIteration,
            BestBreakFactorGroup bestBreakFactorGroup,
            Break theBreak,
            IReadOnlyCollection <Spot> spots,
            decimal?bestBreakScore,
            string message)
        {
            if (!_isloggingEnabled || !_logBestBreakFactor)
            {
                return;
            }

            string file = _logFilenameFactory.FilenameFor(LogFilenameFactory.LogFileType.BestBreak);

            bool addHeaders = !File.Exists(file);
            int  attempts   = 0;

            do
            {
                attempts++;

                try
                {
                    using var writer = new StreamWriter(file, true);
                    if (addHeaders)
                    {
                        writer.WriteLine(string.Format("{1}{0}{2}{0}{3}{0}{4}{0}{5}{0}{6}{0}{7}{0}{8}{0}{9}{0}{10}", Delimiter, "ProcessorDateTime", "PassSeq", "PassIterationSeq", "PlaceSpotsSeq", "GroupName", "GroupSeq", "ExternalBreakRef", "Spots", "BestBreakScore", "Message"));
                    }

                    writer.WriteLine(string.Format("{1}{0}{2}{0}{3}{0}{4}{0}{5}{0}{6}{0}{7}{0}{8}{0}{9}{0}{10}", Delimiter, _processorDateTimeToString,
                                                   smoothPass == null ? "" : smoothPass.Sequence.ToString(),
                                                   smoothPassIteration == null ? "" : smoothPassIteration.Sequence.ToString(),
                                                   0,
                                                   bestBreakFactorGroup == null ? "" : bestBreakFactorGroup.Name,
                                                   bestBreakFactorGroup == null ? "" : bestBreakFactorGroup.Sequence.ToString(),
                                                   theBreak == null ? "" : theBreak.ExternalBreakRef,
                                                   spots == null || spots.Count == 0 ? "" : SpotUtilities.GetListOfSpotExternalReferences(",", spots),
                                                   bestBreakScore == null ? "" : bestBreakScore.Value.ToString("0.000000000000000000000000000000"),
                                                   message));

                    writer.Flush();
                    writer.Close();

                    return;
                }
                catch (Exception exception) when(IsExceptionForFileInUse(exception) && attempts < 10)
                {
                    Thread.Sleep(100);
                }
            } while (attempts != -1);
        }
示例#3
0
 /// <summary>
 /// Executes action to move spot(s) to unplaced list
 /// </summary>
 private void ExecuteMoveToUnplacedAction(
     SmoothPass smoothPass,
     int smoothPassIteration,
     SmoothActionMoveSpotToUnplaced smoothAction,
     IReadOnlyCollection <SmoothBreak> progSmoothBreaks,
     ICollection <Guid> spotIdsUsed,
     bool logSpotAction)
 {
     foreach (var externalSpotRef in smoothAction.ExternalSpotRefs)
     {
         MoveSpotToUnplacedList(
             smoothPass,
             smoothPassIteration,
             externalSpotRef,
             progSmoothBreaks,
             spotIdsUsed,
             logSpotAction);
     }
 }
示例#4
0
        /// <summary>
        /// Moves the spot to the unplaced spots list
        /// </summary>
        private void MoveSpotToUnplacedList(
            SmoothPass smoothPass,
            int smoothPassIteration,
            string externalSpotRef,
            IReadOnlyCollection <SmoothBreak> progSmoothBreaks,
            ICollection <Guid> spotIdsUsed,
            bool logSpotAction)
        {
            // Find the break that spot is placed in
            var smoothBreak = progSmoothBreaks.FirstOrDefault(sb =>
                                                              sb.SmoothSpots.Any(s => s.Spot.ExternalSpotRef == externalSpotRef)
                                                              );

            if (smoothBreak is null)
            {
                return;
            }

            // Spot was placed in break
            var smoothSpot = smoothBreak.SmoothSpots.FirstOrDefault(s =>
                                                                    s.Spot.ExternalSpotRef == externalSpotRef);

            SpotPlacementService.RemoveSpotFromBreak(
                smoothBreak,
                smoothSpot.Spot,
                spotIdsUsed,
                _sponsorshipRestrictionService
                );

            if (logSpotAction)
            {
                _smoothDiagnostics.LogSpotAction(
                    smoothPass,
                    smoothPassIteration,
                    smoothSpot.Spot,
                    smoothBreak,
                    SmoothSpot.SmoothSpotActions.RemoveSpotFromBreak,
                    "Scenario");
            }
        }
示例#5
0
        private void LogBestBreakFactorScore(
            SmoothPass smoothPass,
            SmoothPassDefaultIteration smoothPassIteration,
            SmoothBreak smoothBreak,
            IReadOnlyCollection <Spot> spots,
            decimal breakScore,
            BestBreakFactorGroup bestBreakFactorGroup,
            string scoreDebug,
            string type)
        {
            var spotsDuration = Duration.Zero;

            foreach (var spot in spots)
            {
                spotsDuration = spotsDuration.Plus(spot.SpotLength);
            }

            string spotList = SpotUtilities.GetSpotDetailsListString(spots);

            var message = new StringBuilder(128);

            _ = message
                .AppendFormat("Break={0}; ", smoothBreak.TheBreak.ExternalBreakRef)
                .AppendFormat("BreakDur={0} sec(s);", ((int)smoothBreak.TheBreak.Duration.ToTimeSpan().TotalSeconds).ToString())
                .AppendFormat("Avail={0}s;", ((int)smoothBreak.RemainingAvailability.ToTimeSpan().TotalSeconds).ToString())
                .AppendFormat("SpotsDetails={0}; ", spotList)
                .AppendFormat("SpotsLength={0}s; ", ((int)spotsDuration.ToTimeSpan().TotalSeconds).ToString())
                .AppendFormat("ScoreDebug={0}; ", scoreDebug)
                .AppendFormat("Type={0}", type)
            ;

            _smoothDiagnostics.LogBestBreakFactorMessage(
                smoothPass,
                smoothPassIteration,
                bestBreakFactorGroup,
                smoothBreak.TheBreak,
                spots,
                breakScore,
                message.ToString());
        }
示例#6
0
        /// <summary>
        /// Execute the action to move a spot
        /// </summary>
        private void ExecuteMoveSpotToBreakAction(
            SmoothPass smoothPass,
            int smoothPassIteration,
            SmoothActionMoveSpotToBreak smoothAction,
            IReadOnlyCollection <SmoothBreak> progSmoothBreaks,
            ICollection <Guid> spotIdsUsed,
            bool logSpotAction)
        {
            var externalSpotRefs  = smoothAction.ExternalSpotRefs.ToList();
            var externalBreakRefs = smoothAction.ExternalBreakRefs.ToList();

            for (int index = 0; index < externalSpotRefs.Count; index++)
            {
                MoveSpotToBreak(
                    smoothPass,
                    smoothPassIteration,
                    externalSpotRefs[index],
                    externalBreakRefs[index],
                    progSmoothBreaks,
                    spotIdsUsed,
                    logSpotAction);
            }
        }
示例#7
0
        /// <summary>
        /// Executes the scenario
        /// </summary>
        public void Execute(
            SmoothPass smoothPass,
            int smoothPassIteration,
            SmoothScenario smoothScenario,
            IReadOnlyCollection <SmoothBreak> progSmoothBreaks,
            ICollection <Guid> spotIdsUsed,
            bool logSpotAction)
        {
            foreach (var action in smoothScenario.Actions.OrderBy(a => a.Sequence))
            {
                switch (action)
                {
                case SmoothActionMoveSpotToUnplaced unplaceAction:
                    ExecuteMoveToUnplacedAction(
                        smoothPass,
                        smoothPassIteration,
                        unplaceAction,
                        progSmoothBreaks,
                        spotIdsUsed,
                        logSpotAction);

                    break;

                case SmoothActionMoveSpotToBreak moveToBreakAction:
                    ExecuteMoveSpotToBreakAction(
                        smoothPass,
                        smoothPassIteration,
                        moveToBreakAction,
                        progSmoothBreaks,
                        spotIdsUsed,
                        logSpotAction);

                    break;
                }
            }
        }
示例#8
0
        /// <summary>
        /// Moves the spot to the break
        /// </summary>
        private void MoveSpotToBreak(
            SmoothPass smoothPass,
            int smoothPassIteration,
            string externalSpotRef,
            string externalBreakRef,
            IReadOnlyCollection <SmoothBreak> progSmoothBreaks,
            ICollection <Guid> spotIdsUsed,
            bool logSpotAction)
        {
            // Find the break that spot is placed in
            var srcSmoothBreak = progSmoothBreaks.FirstOrDefault(sb =>
                                                                 sb.SmoothSpots.Any(s => s.Spot.ExternalSpotRef == externalSpotRef)
                                                                 );

            if (srcSmoothBreak is null)
            {
                return;
            }

            SmoothSpot smoothSpot = srcSmoothBreak.SmoothSpots
                                    .First(s => s.Spot.ExternalSpotRef == externalSpotRef);

            SpotPlacementService.RemoveSpotFromBreak(
                srcSmoothBreak,
                smoothSpot.Spot,
                spotIdsUsed,
                _sponsorshipRestrictionService
                );

            if (logSpotAction)
            {
                _smoothDiagnostics.LogSpotAction(
                    smoothPass,
                    smoothPassIteration,
                    smoothSpot.Spot,
                    srcSmoothBreak,
                    SmoothSpot.SmoothSpotActions.RemoveSpotFromBreak,
                    "Scenario");
            }

            // Find the break that spot should be placed in.
            var dstSmoothBreak = progSmoothBreaks.FirstOrDefault(sb =>
                                                                 sb.TheBreak.ExternalBreakRef == externalBreakRef);

            if (dstSmoothBreak is null)
            {
                return;
            }

            _ = SpotPlacementService.AddSpotsToBreak(
                dstSmoothBreak,
                smoothSpot.SmoothPassSequence,
                smoothPassIterationSequence: 0,
                new List <Spot>()
            {
                smoothSpot.Spot
            },
                SpotPositionRules.Exact,
                canMoveSpotToOtherBreak: true,
                spotIdsUsed,
                bestBreakFactorGroupName: null,
                _spotInfos,
                _sponsorshipRestrictionService);

            if (logSpotAction)
            {
                _smoothDiagnostics.LogSpotAction(
                    smoothPass,
                    smoothPassIteration,
                    smoothSpot.Spot,
                    dstSmoothBreak,
                    SmoothSpot.SmoothSpotActions.PlaceSpotInBreak,
                    "Scenario");
            }
        }
示例#9
0
        /// <summary>
        /// Returns best break to add spot(s) to.
        /// </summary>
        public BestBreakResult GetBestBreak(
            SmoothPass smoothPass,
            SmoothPassDefaultIteration smoothPassIteration,
            IReadOnlyCollection <BestBreakFactorGroup> bestBreakFactorGroups,
            IReadOnlyCollection <SmoothBreak> validSmoothBreaks,
            IReadOnlyCollection <Spot> spotsToPlace,
            IReadOnlyDictionary <Guid, SpotInfo> spotInfos,
            IReadOnlyDictionary <string, Clash> clashesByExternalRef,
            IReadOnlyDictionary <string, Product> productsByExternalRef,
            IReadOnlyCollection <SmoothBreak> progSmoothBreaks,
            out BestBreakFactorGroup usedBestBreakFactorGroup)
        {
            var bestBreakResult = new BestBreakResult();

            usedBestBreakFactorGroup = null;

            string breakDetailsListString = BreakUtilities.GetListOfBreakExternalReferences(
                "; ",
                validSmoothBreaks.Select(sb => sb.TheBreak).ToList());

            // Get spot details list as string
            string spotDetailsListString = SpotUtilities.GetSpotDetailsListString(spotsToPlace);

            // Check each group in priority order
            foreach (var bestBreakFactorGroup in bestBreakFactorGroups.OrderBy(g => g.Sequence))
            {
                _smoothDiagnostics.LogBestBreakFactorMessage(
                    smoothPass,
                    smoothPassIteration,
                    bestBreakFactorGroup,
                    null,
                    spotsToPlace,
                    null,
                    $"Checking best break factor group (Breaks={breakDetailsListString}; Spots={spotDetailsListString})"
                    );

                // Set all breaks to check
                var smoothBreaksRemaining = new List <SmoothBreak>();
                smoothBreaksRemaining.AddRange(validSmoothBreaks);

                // Generate unique random score for each break so that we can
                // pick a random break if necessary.
                IReadOnlyCollection <double> randomScoreByBreak = GetRandomScoreByBreak(
                    progSmoothBreaks,
                    uniqueScore: true);

                // Calculate scores for each break, determine best score
                var     scoreByBreak   = new Dictionary <SmoothBreak, decimal>();
                decimal bestBreakScore = -1;

                foreach (var smoothBreak in smoothBreaksRemaining)
                {
                    var(breakScore, scoreDebug) = _bestBreakFactorForGroupService
                                                  .GetBestBreakFactorScoreForGroup(
                        smoothBreak,
                        spotsToPlace,
                        spotInfos,
                        clashesByExternalRef,
                        productsByExternalRef,
                        progSmoothBreaks,
                        randomScoreByBreak,
                        bestBreakFactorGroup,
                        _smoothResources
                        );

                    LogBestBreakFactorScore(
                        smoothPass,
                        smoothPassIteration,
                        smoothBreak,
                        spotsToPlace,
                        breakScore,
                        bestBreakFactorGroup,
                        "Main",
                        scoreDebug
                        );

                    scoreByBreak.Add(smoothBreak, breakScore);

                    if (breakScore > bestBreakScore || bestBreakScore == -1)
                    {
                        bestBreakScore = breakScore;
                    }
                }

                if (bestBreakScore > 0)   // At least one break has a non-zero score
                {
                    // Remove all breaks with score less than the best score
                    var smoothBreaksToRemove = new List <SmoothBreak>();
                    foreach (var smoothBreak in smoothBreaksRemaining)
                    {
                        if (scoreByBreak[smoothBreak] < bestBreakScore)
                        {
                            smoothBreaksToRemove.Add(smoothBreak);
                        }
                    }

                    while (smoothBreaksToRemove.Count > 0)
                    {
                        _ = smoothBreaksRemaining.Remove(smoothBreaksToRemove[0]);
                        smoothBreaksToRemove.RemoveAt(0);
                    }

                    // Single break with best score, return it
                    if (smoothBreaksRemaining.Count == 1)
                    {
                        _smoothDiagnostics.LogBestBreakFactorMessage(
                            smoothPass,
                            smoothPassIteration,
                            bestBreakFactorGroup,
                            smoothBreaksRemaining[0].TheBreak,
                            spotsToPlace,
                            bestBreakScore,
                            $"Using single break which has best score (Spots={spotDetailsListString})"
                            );

                        usedBestBreakFactorGroup    = bestBreakFactorGroup;
                        bestBreakResult.Score       = bestBreakScore;
                        bestBreakResult.SmoothBreak = smoothBreaksRemaining[0];

                        return(bestBreakResult);
                    }

                    // Multiple breaks with best score, determine what we do
                    if (smoothBreaksRemaining.Count > 1)
                    {
                        switch (bestBreakFactorGroup.SameBreakGroupScoreAction)
                        {
                        // Check next group, our default and so no action
                        // required here
                        case SameBreakGroupScoreActions.CheckNextGroup:
                            _smoothDiagnostics.LogBestBreakFactorMessage(
                                smoothPass,
                                smoothPassIteration,
                                bestBreakFactorGroup,
                                null,
                                spotsToPlace,
                                null,
                                "CheckNextGroup: Need to check next group"
                                );
                            break;

                        // Check single factor to identify single break
                        case SameBreakGroupScoreActions.UseSingleBreakFactorIfBestScoreIsNonZero:
                            // Calculate score for each remaining break
                            _smoothDiagnostics.LogBestBreakFactorMessage(
                                smoothPass,
                                smoothPassIteration,
                                bestBreakFactorGroup,
                                null,
                                spotsToPlace,
                                null,
                                $"UseSingleBreakFactorIfBestScoreIsNonZero: Finding break for single break factor score for group (BreaksRemaining={smoothBreaksRemaining.Count.ToString()})"
                                );

                            var     scoreByBreak2   = new Dictionary <SmoothBreak, decimal>();
                            decimal bestBreakScore2 = -1;

                            foreach (var smoothBreak in smoothBreaksRemaining)
                            {
                                decimal breakScore2 = _bestBreakFactorService
                                                      .GetBestBreakFactorScoreForFactor(
                                    smoothBreak,
                                    spotsToPlace,
                                    spotInfos,
                                    clashesByExternalRef,
                                    productsByExternalRef,
                                    progSmoothBreaks,
                                    randomScoreByBreak,
                                    bestBreakFactorGroup.SameBreakGroupScoreFactor,
                                    _smoothResources
                                    );

                                var scoreDebug = $"UseSingleBreakFactorIfBestScoreIsNonZero: {bestBreakFactorGroup.SameBreakGroupScoreFactor.Factor.ToString()}={breakScore2.ToString("0.000000000000000000000000000000")}";

                                LogBestBreakFactorScore(
                                    smoothPass,
                                    smoothPassIteration,
                                    smoothBreak,
                                    spotsToPlace,
                                    breakScore2,
                                    bestBreakFactorGroup,
                                    "",
                                    scoreDebug
                                    );

                                scoreByBreak2.Add(smoothBreak, breakScore2);
                                if (breakScore2 > bestBreakScore2 || bestBreakScore2 == -1)
                                {
                                    bestBreakScore2 = breakScore2;
                                }
                            }

                            // Remove all but the break with the best score
                            var smoothBreaksToRemove2 = new List <SmoothBreak>();
                            foreach (var smoothBreak in smoothBreaksRemaining)
                            {
                                if (scoreByBreak2[smoothBreak] < bestBreakScore2)
                                {
                                    smoothBreaksToRemove2.Add(smoothBreak);
                                }
                            }

                            while (smoothBreaksToRemove2.Count > 0)
                            {
                                _ = smoothBreaksRemaining.Remove(smoothBreaksToRemove2[0]);
                                smoothBreaksToRemove2.RemoveAt(0);
                            }

                            // Return first break Sanity check, if no break
                            // then check next group
                            if (smoothBreaksRemaining.Count > 0)
                            {
                                _smoothDiagnostics.LogBestBreakFactorMessage(
                                    smoothPass,
                                    smoothPassIteration,
                                    bestBreakFactorGroup,
                                    smoothBreaksRemaining[0].TheBreak,
                                    spotsToPlace,
                                    null,
                                    string.Format("UseSingleBreakFactorIfBestScoreIsNonZero: Found break for single break factor score for group (Spots={0}; BreaksRemaining={1})", spotDetailsListString, smoothBreaksRemaining.Count)
                                    );

                                usedBestBreakFactorGroup    = bestBreakFactorGroup;
                                bestBreakResult.Score       = bestBreakScore2;
                                bestBreakResult.SmoothBreak = smoothBreaksRemaining[0];
                                return(bestBreakResult);
                            }
                            else
                            {
                                _smoothDiagnostics.LogBestBreakFactorMessage(
                                    smoothPass,
                                    smoothPassIteration,
                                    bestBreakFactorGroup,
                                    null,
                                    spotsToPlace,
                                    null,
                                    string.Format("UseSingleBreakFactorIfBestScoreIsNonZero: WARNING: Not found break for single break factor score for group (Spots={0}; BreaksRemaining={1})", spotDetailsListString, smoothBreaksRemaining.Count)
                                    );
                            }

                            break;
                        }
                    }
                }
                else    // No break has a non-zero score, check next group
                {
                    _smoothDiagnostics.LogBestBreakFactorMessage(
                        smoothPass,
                        smoothPassIteration,
                        bestBreakFactorGroup,
                        null,
                        spotsToPlace,
                        null,
                        "No breaks with highest score, checking next group"
                        );
                }
            }

            _smoothDiagnostics.LogBestBreakFactorMessage(
                smoothPass,
                smoothPassIteration,
                null,
                null,
                spotsToPlace,
                null,
                "No best break for spots"
                );

            // All groups checked, no best break, shouldn't really happen,
            // possibly bad configuration
            return(bestBreakResult);
        }