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