public static void Improve(Permutation assignment, DoubleMatrix weights, DoubleMatrix distances, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, CancellationToken cancellation)
 {
     for (int i = localIterations.Value; i < maxIterations; i++)
     {
         TranslocationMove bestMove    = null;
         double            bestQuality = 0; // we have to make an improvement, so 0 is the baseline
         double            evaluations = 0.0;
         foreach (var move in ExhaustiveInsertionMoveGenerator.Generate(assignment))
         {
             double moveQuality = QAPTranslocationMoveEvaluator.Apply(assignment, move, weights, distances);
             int    min         = Math.Min(move.Index1, move.Index3);
             int    max         = Math.Max(move.Index2, move.Index3 + (move.Index2 - move.Index1));
             evaluations += 2.0 * (max - min + 1) / assignment.Length
                            + 4.0 * (assignment.Length - (max - min + 1)) / assignment.Length;
             if (maximization && moveQuality > bestQuality ||
                 !maximization && moveQuality < bestQuality)
             {
                 bestQuality = moveQuality;
                 bestMove    = move;
             }
         }
         evaluatedSolutions.Value += (int)Math.Ceiling(evaluations);
         if (bestMove == null)
         {
             break;
         }
         TranslocationManipulator.Apply(assignment, bestMove.Index1, bestMove.Index2, bestMove.Index3);
         quality.Value += bestQuality;
         localIterations.Value++;
         cancellation.ThrowIfCancellationRequested();
     }
 }
コード例 #2
0
        public static void Improve(Permutation assignment, DoubleMatrix distances, DoubleValue quality, IntValue localIterations, IntValue evaluatedSolutions, bool maximization, int maxIterations, DoubleArray probabilities, CancellationToken cancellation)
        {
            var distanceM = (DistanceMatrix)distances;
            Func <int, int, double> distance = (a, b) => distanceM[a, b];

            for (var i = localIterations.Value; i < maxIterations; i++)
            {
                TranslocationMove bestMove = null;
                var bestQuality            = quality.Value; // we have to make an improvement, so current quality is the baseline
                var evaluations            = 0.0;
                foreach (var move in ExhaustiveInsertionMoveGenerator.Generate(assignment))
                {
                    var moveQuality = PTSPAnalyticalInsertionMoveEvaluator.EvaluateMove(assignment, move, distance, probabilities);
                    evaluations++;
                    if (maximization && moveQuality > bestQuality ||
                        !maximization && moveQuality < bestQuality)
                    {
                        bestQuality = moveQuality;
                        bestMove    = move;
                    }
                }
                evaluatedSolutions.Value += (int)Math.Ceiling(evaluations);
                if (bestMove == null)
                {
                    break;
                }
                TranslocationManipulator.Apply(assignment, bestMove.Index1, bestMove.Index2, bestMove.Index3);
                quality.Value = bestQuality;
                localIterations.Value++;
                cancellation.ThrowIfCancellationRequested();
            }
        }
コード例 #3
0
        public void TranslocationMoveEvaluatorTest()
        {
            var    evaluator         = new TSPRoundedEuclideanPathEvaluator();
            var    moveEvaluator     = new TSPTranslocationMoveRoundedEuclideanPathEvaluator();
            double beforeMatrix      = TSPDistanceMatrixEvaluator.Apply(distances, tour);
            double beforeCoordinates = TSPCoordinatesPathEvaluator.Apply(evaluator, coordinates, tour);

            Assert.IsTrue(beforeMatrix.IsAlmost(beforeCoordinates), "Evaluation differs between using the coordinates and using the distance matrix.");

            for (int i = 0; i < 500; i++)
            {
                var move = StochasticTranslocationSingleMoveGenerator.Apply(tour, random);

                double moveMatrix      = TSPTranslocationMovePathEvaluator.EvaluateByDistanceMatrix(tour, move, distances);
                double moveCoordinates = TSPTranslocationMovePathEvaluator.EvaluateByCoordinates(tour, move, coordinates, moveEvaluator);
                Assert.IsTrue(moveMatrix.IsAlmost(moveCoordinates), "Evaluation differs between using the coordinates and using the distance matrix.");

                string failureString = string.Format(@"Translocation move is calculated with quality {0}, but actual difference is {5}.
The move would move the segment between {1} and {2} in the tour {3} to the new index {4}.", moveMatrix.ToString(), tour[move.Index1].ToString(), tour[move.Index2].ToString(), tour.ToString(), move.Index3.ToString(), "{0}");
                TranslocationManipulator.Apply(tour, move.Index1, move.Index2, move.Index3);

                double afterMatrix      = TSPDistanceMatrixEvaluator.Apply(distances, tour);
                double afterCoordinates = TSPCoordinatesPathEvaluator.Apply(evaluator, coordinates, tour);
                Assert.IsTrue(afterMatrix.IsAlmost(afterCoordinates), "Evaluation differs between using the coordinates and using the distance matrix.");

                Assert.IsTrue(moveMatrix.IsAlmost(afterMatrix - beforeMatrix), string.Format(failureString, (afterMatrix - beforeMatrix).ToString()));

                beforeMatrix      = afterMatrix;
                beforeCoordinates = afterCoordinates;
            }
        }
コード例 #4
0
        public static double EvaluateMove(Permutation tour, TranslocationMove move, Func <int, int, double> distance, DoubleArray probabilities)
        {
            var afterMove = (Permutation)tour.Clone();

            TranslocationManipulator.Apply(afterMove, move.Index1, move.Index1, move.Index3);
            return(AnalyticalProbabilisticTravelingSalesmanProblem.Evaluate(afterMove, distance, probabilities));
        }
コード例 #5
0
        public override double EvaluateMove(Permutation permutation, TranslocationMove move, PackingShape binShape,
                                            ReadOnlyItemList <PackingItem> items)
        {
            // uses full evaluation
            TranslocationManipulator.Apply(permutation, move.Index1, move.Index2, move.Index3);
            var solution = DecoderParameter.ActualValue.Decode(permutation, binShape, items);

            return(SolutionEvaluatorParameter.ActualValue.Evaluate(solution));
        }
コード例 #6
0
        protected override void EvaluateMove()
        {
            TranslocationMove move = TranslocationMoveParameter.ActualValue;
            //perform move
            AlbaEncoding newSolution = move.Permutation.Clone() as AlbaEncoding;

            TranslocationManipulator.Apply(newSolution, move.Index1, move.Index2, move.Index3);

            UpdateEvaluation(newSolution);
        }
コード例 #7
0
 public static void Apply(Permutation permutation, TwoPointFiveMove move)
 {
     if (move.IsInvert)
     {
         InversionManipulator.Apply(permutation, move.Index1, move.Index2);
     }
     else
     {
         TranslocationManipulator.Apply(permutation, move.Index1, move.Index1, move.Index2);
     }
 }
コード例 #8
0
        public void TranslocationManipulatorApplyTest()
        {
            TestRandom  random = new TestRandom();
            Permutation parent, expected;

            // The following test is based on an example from Larranaga, P. et al. 1999. Genetic Algorithms for the Travelling Salesman Problem: A Review of Representations and Operators. Artificial Intelligence Review, 13, p. 24
            random.Reset();
            random.IntNumbers = new int[] { 2, 4, 4 };
            parent            = new Permutation(PermutationTypes.RelativeUndirected, new int[] { 0, 1, 2, 3, 4, 5, 6, 7 });
            Assert.IsTrue(parent.Validate());

            expected = new Permutation(PermutationTypes.RelativeUndirected, new int[] { 0, 1, 5, 6, 2, 3, 4, 7 });
            Assert.IsTrue(expected.Validate());
            TranslocationManipulator.Apply(random, parent);
            Assert.IsTrue(parent.Validate());
            Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, parent));
        }
コード例 #9
0
        public void TranslocationMoveEvaluatorTest()
        {
            for (int i = 0; i < 500; i++)
            {
                int index1           = random.Next(assignment.Length - 1);
                int index2           = random.Next(index1 + 1, assignment.Length);
                int insertPointLimit = assignment.Length - index2 + index1 - 1; // get insertion point in remaining part
                int insertPoint;
                if (insertPointLimit > 0)
                {
                    insertPoint = random.Next(insertPointLimit);
                }
                else
                {
                    insertPoint = 0;
                }

                // SYMMETRIC MATRICES
                double      before = QAPEvaluator.Apply(assignment, symmetricWeights, symmetricDistances);
                Permutation clone  = new Cloner().Clone(assignment);
                TranslocationManipulator.Apply(assignment, index1, index2, insertPoint);
                double after = QAPEvaluator.Apply(assignment, symmetricWeights, symmetricDistances);
                double move  = QAPTranslocationMoveEvaluator.Apply(clone, new TranslocationMove(index1, index2, insertPoint, assignment), symmetricWeights, symmetricDistances);
                Assert.IsTrue(move.IsAlmost(after - before), "Failed on symmetric matrices");

                // ASYMMETRIC MATRICES
                before = QAPEvaluator.Apply(assignment, asymmetricWeights, asymmetricDistances);
                clone  = new Cloner().Clone(assignment);
                TranslocationManipulator.Apply(assignment, index1, index2, insertPoint);
                after = QAPEvaluator.Apply(assignment, asymmetricWeights, asymmetricDistances);
                move  = QAPTranslocationMoveEvaluator.Apply(clone, new TranslocationMove(index1, index2, insertPoint, assignment), asymmetricWeights, asymmetricDistances);
                Assert.IsTrue(move.IsAlmost(after - before), "Failed on asymmetric matrices");

                // NON-ZERO DIAGONAL ASYMMETRIC MATRICES
                before = QAPEvaluator.Apply(assignment, nonZeroDiagonalWeights, nonZeroDiagonalDistances);
                clone  = new Cloner().Clone(assignment);
                TranslocationManipulator.Apply(assignment, index1, index2, insertPoint);
                after = QAPEvaluator.Apply(assignment, nonZeroDiagonalWeights, nonZeroDiagonalDistances);
                move  = QAPTranslocationMoveEvaluator.Apply(clone, new TranslocationMove(index1, index2, insertPoint, assignment), nonZeroDiagonalWeights, nonZeroDiagonalDistances);
                Assert.IsTrue(move.IsAlmost(after - before), "Failed on non-zero diagonal matrices");
            }
        }
コード例 #10
0
        public void InsertionMoveEvaluatorTest()
        {
            Func <int, int, double> distance = (a, b) => distances[a, b];
            double variance;
            var    beforeMatrix = EstimatedProbabilisticTravelingSalesmanProblem.Evaluate(tour, distance, realizations, out variance);

            for (var i = 0; i < 500; i++)
            {
                var move       = StochasticTranslocationSingleMoveGenerator.Apply(tour, random);
                var moveMatrix = PTSPEstimatedInsertionMoveEvaluator.EvaluateMove(tour, move, distance, realizations);
                TranslocationManipulator.Apply(tour, move.Index1, move.Index1, move.Index3);
                var afterMatrix = EstimatedProbabilisticTravelingSalesmanProblem.Evaluate(tour, distance, realizations, out variance);

                Assert.IsTrue(Math.Abs(moveMatrix).IsAlmost(Math.Abs(afterMatrix - beforeMatrix)),
                              string.Format(@"Insertion move is calculated with quality {0}, but actual difference is {4}.
The move would invert the tour {1} between values {2} and {3}.",
                                            moveMatrix, tour, tour[move.Index1], tour[move.Index2], Math.Abs(afterMatrix - beforeMatrix)));

                beforeMatrix = afterMatrix;
            }
        }
        public static double EvaluateMove(Permutation tour, TranslocationMove move, Func <int, int, double> distance, ItemList <BoolArray> realizations)
        {
            var afterMove = (Permutation)tour.Clone();

            TranslocationManipulator.Apply(afterMove, move.Index1, move.Index1, move.Index3);
            double moveQuality = 0;
            var    edges       = new int[12];
            var    indices     = new int[12];

            edges[0]   = tour.GetCircular(move.Index1 - 1);
            indices[0] = DecreaseCircularIndex(tour.Length, move.Index1);
            edges[1]   = tour[move.Index1];
            indices[1] = move.Index1;
            edges[2]   = tour[move.Index1];
            indices[2] = move.Index1;
            edges[3]   = tour.GetCircular(move.Index1 + 1);
            indices[3] = IncreaseCircularIndex(tour.Length, move.Index1);

            edges[6]   = afterMove.GetCircular(move.Index3 - 1);
            indices[6] = DecreaseCircularIndex(afterMove.Length, move.Index3);
            edges[7]   = afterMove[move.Index3];
            indices[7] = move.Index3;
            edges[8]   = afterMove[move.Index3];
            indices[8] = move.Index3;
            edges[9]   = afterMove.GetCircular(move.Index3 + 1);
            indices[9] = IncreaseCircularIndex(afterMove.Length, move.Index3);

            if (move.Index3 > move.Index1)
            {
                edges[4]    = tour[move.Index3];
                indices[4]  = move.Index3;
                edges[5]    = tour.GetCircular(move.Index3 + 1);
                indices[5]  = indices[9];
                edges[10]   = afterMove.GetCircular(move.Index1 - 1);
                indices[10] = indices[0];
                edges[11]   = afterMove[move.Index1];
                indices[11] = move.Index1;
            }
            else
            {
                edges[4]    = tour.GetCircular(move.Index3 - 1);
                indices[4]  = indices[6];
                edges[5]    = tour[move.Index3];
                indices[5]  = move.Index3;
                edges[10]   = afterMove[move.Index1];
                indices[10] = move.Index1;
                edges[11]   = afterMove.GetCircular(move.Index1 + 1);
                indices[11] = indices[3];
            }
            int[] aPosteriori = new int[12];
            foreach (var realization in realizations)
            {
                for (int i = 0; i < edges.Length; i++)
                {
                    Permutation tempPermutation;
                    if (i < 6)
                    {
                        tempPermutation = tour;
                    }
                    else
                    {
                        tempPermutation = afterMove;
                    }
                    if (realization[edges[i]])
                    {
                        aPosteriori[i] = edges[i];
                    }
                    else
                    {
                        int j = 1;
                        if (i % 2 == 0)
                        {
                            // find nearest predecessor in realization if source edge
                            while (!realization[tempPermutation.GetCircular(indices[i] - j)])
                            {
                                j++;
                            }
                            aPosteriori[i] = tempPermutation.GetCircular(indices[i] - j);
                        }
                        else
                        {
                            // find nearest successor in realization if target edge
                            while (!realization[tempPermutation.GetCircular(indices[i] + j)])
                            {
                                j++;
                            }
                            aPosteriori[i] = tempPermutation.GetCircular(indices[i] + j);
                        }
                    }
                }
                if (!(aPosteriori[0] == aPosteriori[2] && aPosteriori[1] == aPosteriori[3]) &&
                    !(aPosteriori[0] == aPosteriori[4] && aPosteriori[1] == aPosteriori[5]) &&
                    !(aPosteriori[2] == aPosteriori[4] && aPosteriori[3] == aPosteriori[5]))
                {
                    // compute cost difference between the two a posteriori solutions
                    moveQuality = moveQuality + distance(aPosteriori[6], aPosteriori[7]) + distance(aPosteriori[8], aPosteriori[9]) + distance(aPosteriori[10], aPosteriori[11]);
                    moveQuality = moveQuality - distance(aPosteriori[0], aPosteriori[1]) - distance(aPosteriori[2], aPosteriori[3]) - distance(aPosteriori[4], aPosteriori[5]);
                }
                Array.Clear(aPosteriori, 0, aPosteriori.Length);
            }
            // return average of cost differences
            return(moveQuality / realizations.Count);
        }