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()); }
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; } }
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; } }