public static double EvaluateMove(Permutation tour, InversionMove move, Func <int, int, double> distance, DoubleArray probabilities) { var afterMove = (Permutation)tour.Clone(); InversionManipulator.Apply(afterMove, move.Index1, move.Index2); return(AnalyticalProbabilisticTravelingSalesmanProblem.Evaluate(afterMove, distance, probabilities)); }
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++) { InversionMove 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 ExhaustiveInversionMoveGenerator.Generate(assignment)) { var moveQuality = PTSPAnalyticalInversionMoveEvaluator.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; } InversionManipulator.Apply(assignment, bestMove.Index1, bestMove.Index2); quality.Value = bestQuality; localIterations.Value++; cancellation.ThrowIfCancellationRequested(); } }
public static double Apply(Permutation assignment, InversionMove move, DoubleMatrix weights, DoubleMatrix distances) { if (move.Index1 == move.Index2) { return(0); } double moveQuality = 0; int min = Math.Min(move.Index1, move.Index2); int max = Math.Max(move.Index1, move.Index2); for (int i = min; i <= max; i++) { int locI = assignment[i]; int newlocI = assignment[max - i + min]; for (int j = 0; j < assignment.Length; j++) { int locJ = assignment[j]; if (j >= min && j <= max) { int newlocJ = assignment[max - j + min]; moveQuality += weights[i, j] * (distances[newlocI, newlocJ] - distances[locI, locJ]); } else { moveQuality += weights[i, j] * (distances[newlocI, locJ] - distances[locI, locJ]); moveQuality += weights[j, i] * (distances[locJ, newlocI] - distances[locJ, locI]); } } } return(moveQuality); }
public static double EvaluateByCoordinates(Permutation permutation, InversionMove move, DoubleMatrix coordinates, TSPInversionMovePathEvaluator evaluator) { int edge1source = permutation.GetCircular(move.Index1 - 1); int edge1target = permutation[move.Index1]; int edge2source = permutation[move.Index2]; int edge2target = permutation.GetCircular(move.Index2 + 1); if (move.Index2 - move.Index1 >= permutation.Length - 2) { return(0); } double moveQuality = 0; // remove two edges moveQuality -= evaluator.CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1], coordinates[edge1target, 0], coordinates[edge1target, 1]); moveQuality -= evaluator.CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1], coordinates[edge2target, 0], coordinates[edge2target, 1]); // add two edges moveQuality += evaluator.CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1], coordinates[edge2source, 0], coordinates[edge2source, 1]); moveQuality += evaluator.CalculateDistance(coordinates[edge1target, 0], coordinates[edge1target, 1], coordinates[edge2target, 0], coordinates[edge2target, 1]); return(moveQuality); }
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++) { InversionMove bestMove = null; double bestQuality = 0; // we have to make an improvement, so 0 is the baseline double evaluations = 0.0; foreach (var move in ExhaustiveInversionMoveGenerator.Generate(assignment)) { double moveQuality = QAPInversionMoveEvaluator.Apply(assignment, move, weights, distances); evaluations += 2 * (move.Index2 - move.Index1 + 1) / (double)assignment.Length; if (maximization && moveQuality > bestQuality || !maximization && moveQuality < bestQuality) { bestQuality = moveQuality; bestMove = move; } } evaluatedSolutions.Value += (int)Math.Ceiling(evaluations); if (bestMove == null) { break; } InversionManipulator.Apply(assignment, bestMove.Index1, bestMove.Index2); 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, ItemList <BoolArray> realizations, CancellationToken cancellation) { var distanceM = (DistanceMatrix)distances; Func <int, int, double> distance = (a, b) => distanceM[a, b]; for (var i = localIterations.Value; i < maxIterations; i++) { InversionMove bestMove = null; double bestQuality = 0; // we have to make an improvement, so 0 is the baseline double evaluations = 0.0; foreach (var move in ExhaustiveInversionMoveGenerator.Generate(assignment)) { double moveQuality = PTSPEstimatedInversionMoveEvaluator.EvaluateMove(assignment, move, distance, realizations); evaluations += realizations.Count * 4.0 / (assignment.Length * assignment.Length); if (maximization && moveQuality > bestQuality || !maximization && moveQuality < bestQuality) { bestQuality = moveQuality; bestMove = move; } } evaluatedSolutions.Value += (int)Math.Ceiling(evaluations); if (bestMove == null) { break; } InversionManipulator.Apply(assignment, bestMove.Index1, bestMove.Index2); quality.Value += bestQuality; localIterations.Value++; cancellation.ThrowIfCancellationRequested(); } }
public override IOperation Apply() { InversionMove move = InversionMoveParameter.ActualValue; if (move == null) { throw new InvalidOperationException("Inversion move is not found."); } Permutation assignment = PermutationParameter.ActualValue; DoubleMatrix distances = DistancesParameter.ActualValue; DoubleMatrix weights = WeightsParameter.ActualValue; double moveQuality = QualityParameter.ActualValue.Value; moveQuality += Apply(assignment, move, weights, distances); MoveQualityParameter.ActualValue = new DoubleValue(moveQuality); return(base.Apply()); }
public static double EvaluateByDistanceMatrix(Permutation permutation, InversionMove move, DistanceMatrix distanceMatrix) { int edge1source = permutation.GetCircular(move.Index1 - 1); int edge1target = permutation[move.Index1]; int edge2source = permutation[move.Index2]; int edge2target = permutation.GetCircular(move.Index2 + 1); if (move.Index2 - move.Index1 >= permutation.Length - 2) { return(0); } double moveQuality = 0; // remove two edges moveQuality -= distanceMatrix[edge1source, edge1target]; moveQuality -= distanceMatrix[edge2source, edge2target]; // add two edges moveQuality += distanceMatrix[edge1source, edge2source]; moveQuality += distanceMatrix[edge1target, edge2target]; return(moveQuality); }
public static double EvaluateMove(Permutation tour, InversionMove move, Func <int, int, double> distance, ItemList <BoolArray> realizations) { double moveQuality = 0; var edges = new int[4]; var indices = new int[4]; edges[0] = tour.GetCircular(move.Index1 - 1); indices[0] = move.Index1 - 1; if (indices[0] == -1) { indices[0] = tour.Length - 1; } edges[1] = tour[move.Index1]; indices[1] = move.Index1; edges[2] = tour[move.Index2]; indices[2] = move.Index2; edges[3] = tour.GetCircular(move.Index2 + 1); indices[3] = move.Index2 + 1; if (indices[3] == tour.Length + 1) { indices[3] = 0; } var aPosteriori = new int[4]; foreach (var realization in realizations) { for (var i = 0; i < edges.Length; i++) { if (realization[edges[i]]) { aPosteriori[i] = edges[i]; } else { var j = 1; if (i % 2 == 0) { // find nearest predecessor in realization if source edge while (!realization[tour.GetCircular(indices[i] - j)]) { j++; } aPosteriori[i] = tour.GetCircular(indices[i] - j); } else { // find nearest successor in realization if target edge while (!realization[tour.GetCircular(indices[i] + j)]) { j++; } aPosteriori[i] = tour.GetCircular(indices[i] + j); } } } // compute cost difference between the two a posteriori solutions if (!(aPosteriori[0] == aPosteriori[2] && aPosteriori[1] == aPosteriori[3])) { moveQuality = moveQuality + distance(aPosteriori[0], aPosteriori[2]) + distance(aPosteriori[1], aPosteriori[3]) - distance(aPosteriori[0], aPosteriori[1]) - distance(aPosteriori[2], aPosteriori[3]); } Array.Clear(aPosteriori, 0, aPosteriori.Length); } // return average of cost differences return(moveQuality / realizations.Count); }