Ejemplo n.º 1
0
        public void UpdateTimes()
        {
            if (_necessaryFixes.Count == 0)
            {
                return;
            }

            ClassInvariant();
            UpdateTimesLoopInvariant();

            while (_necessaryFixes.Count > 0)
            {
                int current = _necessaryFixes.Min.Vertex;
                _necessaryFixes.Remove(_necessaryFixes.Min);

                foreach (Arc arc in OutgoingArcs(current))
                {
                    if (Solution.GetEntryTime(arc.Head) < Solution.GetEntryTime(arc.Tail) + arc.Length)
                    {
                        CostLayer.SetEntryTime(arc.Head, Solution.GetEntryTime(arc.Tail) + arc.Length);
                        _necessaryFixes.Add(new TimeAtVertex(arc.Head, Solution.GetEntryTime(arc.Tail) + arc.Length));
                    }

                    else if (Solution.GetEntryTime(arc.Head) > Solution.GetEntryTime(arc.Tail) + arc.Length)
                    {
                        TimeSpan oldTime = Solution.GetEntryTime(arc.Head);
                        TimeSpan newTime = IncomingArcs(arc.Head)
                                           .Select(a => Solution.GetEntryTime(a.Tail) + a.Length)
                                           .Append(Solution.GetOperation(arc.Head).EarliestEarliestEntry)
                                           .Max();

                        if (oldTime != newTime)
                        {
                            CostLayer.SetEntryTime(arc.Head, newTime);
                            _necessaryFixes.Add(new TimeAtVertex(arc.Head, newTime));
                        }
                    }
                }

                UpdateTimesLoopInvariant();
            }

            ClassInvariant();
            TimesGraphIntegrity.DoCheck(this);
        }
Ejemplo n.º 2
0
        public IEnumerable <Arc> GetCriticalArcs(IEnumerable <int> backtrackFrom, bool onlyDisjunctive = true)
        {
            if (!TimesAreUpToDate())
            {
                throw new Exception();
            }

            TimesGraphIntegrity.DoCheck(this);
            ClassInvariant();

            // used iff obj == max weighted tardiness
            HashSet <int> alreadyReturned = new HashSet <int>();

            var indicesOfCosts = backtrackFrom;

            foreach (int vertex in indicesOfCosts)
            {
                int current = vertex;

                while (true)
                {
                    if (alreadyReturned.Contains(current))
                    {
                        break;
                    }

                    alreadyReturned.Add(current);

                    if (!_graph.IncomingArcs(current).Any())
                    {
                        break;
                    }

                    Arc arc = _graph.IncomingArcs(current)
                              .FirstOrDefault(a => Solution.GetEntryTime(a.Head) == Solution.GetEntryTime(a.Tail) + a.Length);

                    if (arc.Equals(default))
Ejemplo n.º 3
0
        private static IJobShopLayer Step(
            int iteration,
            IJobShopLayer origin,
            double bestCost,
            ITabooList tabooList,
            Random random,
            double moveImmediatelyImprovementRate = 0.00001,  // improvement >= 0.001% -> move to the next solution immediately
            int minArcsToCheckCount = 1,
            bool verbose            = true)
        {
            TimesGraphIntegrity.DoCheck(origin.RoutingLayer.ClosureLayer.SequencingLayer.GraphLayer);

            var moves = GetMoves(origin, tabooList, random);

            if (moves.Length == 0)
            {
                throw new NoMoves();
            }

            if (verbose)
            {
                Console.WriteLine($"Inspecting {moves.Length} moves.");
            }

            //TabooType[] tabooTypes = new TabooType[moves.Length]; // init all to 'unknown'

            if (tabooList.Any())
            {
                for (int i = 0; i < moves.Length; i++)
                {
                    if (tabooList.IsAprioriTaboo(moves[i].ActualMove))
                    {
                        moves[i].TabooType = TabooType.AprioriTaboo;
                    }
                }
            }

            double originCost = origin.GetTotalCost();

            //double[] resultCosts = Enumerable.Repeat(double.MaxValue, moves.Length).ToArray();

            // Try the moves.
            for (int i = 0; i < moves.Length; i++)
            {
                if (moves[i].TabooType == TabooType.AprioriTaboo)
                {
                    if (verbose)
                    {
                        Console.Write(ShortToString(moves[i].TabooType) + " ");
                    }
                    continue;
                }

                // Clone & execute.
                var clone = origin.Clone();
                clone.ExecuteMove(moves[i].ActualMove);
                moves[i].Cost = clone.GetTotalCost();

                // Never trust yourself
                Assert(SingleThreadSearchChecks, clone.GetHashCode() != origin.GetHashCode() || !clone.Equals(origin));

                // decide if the move is taboo
                if (!tabooList.Any())
                {
                    moves[i].TabooType = TabooType.NotTaboo;
                }

                else if (moves[i].Cost < 0.9999 * bestCost)
                {
                    moves[i].TabooType = TabooType.Ascension;
                }

                else if (tabooList.IsAposterioriTaboo(clone))
                {
                    moves[i].TabooType = TabooType.AposterioriTaboo;
                }

                else
                {
                    moves[i].TabooType = TabooType.NotTaboo;
                }

                if (verbose)
                {
                    Console.Write(
                        ShortToString(moves[i].TabooType)
                        + (moves[i].Cost < 0.9999 * originCost? "^" : "")
                        + " ");
                }

                // break, if the improvement is large enough (&& not taboo).
                double improvementRate = (bestCost - moves[i].Cost) / bestCost;

                if (i > minArcsToCheckCount &&
                    improvementRate > moveImmediatelyImprovementRate &&
                    (moves[i].TabooType == TabooType.Ascension || moves[i].TabooType == TabooType.NotTaboo))
                {
                    break;
                }
            }

            if ((iteration % 10) == 0)
            {
                //Console.WriteLine("hello...");
            }

            // Find the move to return.
            int  candidateIndex = -1;
            Move candidate      = null;

            for (int i = 0; i < moves.Length; i++)
            {
                var move  = moves[i];
                var taboo = moves[i].TabooType;

                if ((candidateIndex == -1 || moves[i].Cost < moves[candidateIndex].Cost) &&
                    taboo != TabooType.AposterioriTaboo &&
                    taboo != TabooType.AprioriTaboo)
                {
                    candidateIndex = i;
                    candidate      = move.ActualMove;
                }
            }

            Assert(SingleThreadSearchChecks, candidate != null);

            if (candidate == null)
            {
                Console.WriteLine("all moves taboo!");
                double minCost = moves.Select(m => m.Cost).Min();
                candidateIndex = Enumerable.Range(0, moves.Length).First(i => (moves[i].Cost == minCost));
                candidate      = moves[candidateIndex].ActualMove;
            }

            if (moves[candidateIndex].Cost > 0.9999 * bestCost)
            {
                tabooList.ProhibitUndoOfMove(origin, candidate);

                Assert(SingleThreadSearchChecks, tabooList.IsAprioriTaboo(candidate) ||
                       tabooList.IsAposterioriTaboo(origin),
                       "When adding elements to the taboo-list, the original solution (before executing the move) must be taboo.");

                if (SingleThreadSearchChecks.On &&
                    (candidate.Type == MoveType.RemoveCriticalArcLeftClosure ||
                     candidate.Type == MoveType.RemoveCriticalArcRightClosure))
                {
                    Assert(SingleThreadSearchChecks, origin.TransitiveArcExist(candidate.CriticalArc));
                    var target = origin.Clone();
                    target.ExecuteMove(candidate);
                    Assert(SingleThreadSearchChecks, !target.TransitiveArcExist(candidate.CriticalArc));
                }
            }

            // Execute this move & return.
            origin.ExecuteMove(candidate);
            return(origin);
        }