Esempio n. 1
0
        public override IOperation Apply()
        {
            var solution = CurrentScope.Variables[SolutionParameter.ActualName].Value as Permutation;

            if (solution == null)
            {
                throw new ArgumentException("Cannot improve solution because it has the wrong type.");
            }
            if (solution.PermutationType != PermutationTypes.RelativeUndirected)
            {
                throw new ArgumentException("Cannot improve solution because the permutation type is not supported.");
            }

            for (int i = 0; i < ImprovementAttempts.Value; i++)
            {
                var    move        = StochasticInversionSingleMoveGenerator.Apply(solution, Random);
                double moveQualtiy = TSPInversionMovePathEvaluator.EvaluateByDistanceMatrix(solution, move, DistanceMatrix);
                if (moveQualtiy < 0)
                {
                    InversionManipulator.Apply(solution, move.Index1, move.Index2);
                }
            }

            CurrentScope.Variables.Add(new Variable("LocalEvaluatedSolutions", ImprovementAttempts));

            return(base.Apply());
        }
Esempio n. 2
0
        public void InversionMoveEvaluatorTest()
        {
            var    evaluator         = new TSPRoundedEuclideanPathEvaluator();
            var    moveEvaluator     = new TSPInversionMoveRoundedEuclideanPathEvaluator();
            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 = StochasticInversionSingleMoveGenerator.Apply(tour, random);

                double moveMatrix      = TSPInversionMovePathEvaluator.EvaluateByDistanceMatrix(tour, move, distances);
                double moveCoordinates = TSPInversionMovePathEvaluator.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(@"Inversion move is calculated with quality {0}, but actual difference is {4}.
The move would invert the tour {1} between values {2} and {3}.", moveMatrix.ToString(), tour.ToString(), tour[move.Index1].ToString(), tour[move.Index2].ToString(), "{0}");

                InversionManipulator.Apply(tour, move.Index1, move.Index2);

                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;
            }
        }
Esempio n. 3
0
        public void InversionMoveEvaluatorTest()
        {
            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       = StochasticInversionSingleMoveGenerator.Apply(tour, random);
                var moveMatrix = PTSPEstimatedInversionMoveEvaluator.EvaluateMove(tour, move, distance, realizations);
                InversionManipulator.Apply(tour, move.Index1, move.Index2);
                var afterMatrix = EstimatedProbabilisticTravelingSalesmanProblem.Evaluate(tour, distance, realizations, out variance);

                Assert.IsTrue(Math.Abs(moveMatrix).IsAlmost(Math.Abs(afterMatrix - beforeMatrix)),
                              string.Format(@"Inversion 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;
            }
        }