Esempio n. 1
0
        private static SearchMove[] GetMoves(IJobShopLayer origin, ITabooList tabooList, Random random)
        {
            if (origin.GetConnectionsCost() > .5 * origin.GetTotalCost())
            {
                return(origin.GetMoves(
                           connectionFix: true,
                           connectionImprovement: true,
                           criticalArcsBased: tabooList.Any(),
                           routeSwapBased: false,
                           routeSwapWithHeuristicInsertion: false, //true, //!tabooList.Any(),
                           jobReinsertion: false,
                           routePenaltyImprovement: false)
                       .Shuffle(random)
                       .Select(m => new SearchMove(m))
                       .ToArray());
            }

            if (origin.GetDelayCost() > origin.GetRoutingCost())
            {
                bool changeRoute = !tabooList.Any() || random.NextDouble() < .3;

                return(origin
                       .GetMoves(
                           connectionFix: true,
                           connectionImprovement: true,
                           criticalArcsBased: true,
                           routeSwapBased: changeRoute,
                           routeSwapWithHeuristicInsertion: changeRoute, //true, //!tabooList.Any(),
                           jobReinsertion: changeRoute,
                           routePenaltyImprovement: false)
                       .Shuffle(random)
                       .Select(m => new SearchMove(m))
                       .ToArray());
            }
            else
            {
                return(origin
                       .GetMoves(false, false, false, false, false, false, routePenaltyImprovement: true)
                       .Shuffle(random).Select(m => new SearchMove(m)).ToArray());
            }
        }
Esempio n. 2
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);
        }