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 override IOperation InstrumentedApply() { IOperation next = base.InstrumentedApply(); IVRPEncoding solution = VRPToursParameter.ActualValue; generator.PermutationParameter.ActualName = VRPToursParameter.ActualName; IAtomicOperation op = this.ExecutionContext.CreateChildOperation(generator); op.Operator.Execute((IExecutionContext)op, CancellationToken); foreach (IScope scope in this.ExecutionContext.Scope.SubScopes) { IVariable moveVariable = scope.Variables[ TranslocationMoveParameter.ActualName]; if (moveVariable.Value is TranslocationMove && !(moveVariable.Value is AlbaTranslocationMove)) { TranslocationMove move = moveVariable.Value as TranslocationMove; moveVariable.Value = new AlbaTranslocationMove( move.Index1, move.Index2, move.Index3, solution as AlbaEncoding); } } return(next); }
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 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)); }
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); }
protected override void PerformMove() { IVariable moveVariable = this.ExecutionContext.Scope.Variables[ TranslocationMoveParameter.ActualName]; TranslocationMove move = moveVariable.Value as TranslocationMove; VRPToursParameter.ActualValue = move.Permutation as AlbaEncoding; moveMaker.PermutationParameter.ActualName = VRPToursParameter.ActualName; IAtomicOperation op = this.ExecutionContext.CreateChildOperation(moveMaker); op.Operator.Execute((IExecutionContext)op, CancellationToken); }
public static double Apply(Permutation assignment, TranslocationMove move, DoubleMatrix weights, DoubleMatrix distances) { double moveQuality = 0; int min = Math.Min(move.Index1, move.Index3); int max = Math.Max(move.Index2, move.Index3 + (move.Index2 - move.Index1)); int iOffset, changeOffset; if (move.Index1 < move.Index3) { iOffset = move.Index2 - move.Index1 + 1; changeOffset = min + max - move.Index2; } else { iOffset = move.Index1 - move.Index3; changeOffset = min + move.Index2 - move.Index1 + 1; } for (int i = min; i <= max; i++) { if (i == changeOffset) { iOffset -= (max - min + 1); } int jOffset = ((move.Index1 < move.Index3) ? (move.Index2 - move.Index1 + 1) : (move.Index1 - move.Index3)); for (int j = 0; j < assignment.Length; j++) { moveQuality -= weights[i, j] * distances[assignment[i], assignment[j]]; if (j < min || j > max) { moveQuality -= weights[j, i] * distances[assignment[j], assignment[i]]; moveQuality += weights[i, j] * distances[assignment[i + iOffset], assignment[j]]; moveQuality += weights[j, i] * distances[assignment[j], assignment[i + iOffset]]; } else { if (j == changeOffset) { jOffset -= (max - min + 1); } moveQuality += weights[i, j] * distances[assignment[i + iOffset], assignment[j + jOffset]]; } } } return(moveQuality); }
public override IOperation Apply() { TranslocationMove move = TranslocationMoveParameter.ActualValue; if (move == null) { throw new InvalidOperationException("Translocation 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 EvaluateByCoordinates(Permutation permutation, TranslocationMove move, DoubleMatrix coordinates, TSPTranslocationMovePathEvaluator evaluator) { if (move.Index1 == move.Index3 || move.Index2 == permutation.Length - 1 && move.Index3 == 0 || move.Index1 == 0 && move.Index3 == permutation.Length - 1 - move.Index2) { return(0); } int edge1source = permutation.GetCircular(move.Index1 - 1); int edge1target = permutation[move.Index1]; int edge2source = permutation[move.Index2]; int edge2target = permutation.GetCircular(move.Index2 + 1); int edge3source, edge3target; if (move.Index3 > move.Index1) { edge3source = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1); edge3target = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1 + 1); } else { edge3source = permutation.GetCircular(move.Index3 - 1); edge3target = permutation[move.Index3]; } double moveQuality = 0; // remove three 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]); moveQuality -= evaluator.CalculateDistance(coordinates[edge3source, 0], coordinates[edge3source, 1], coordinates[edge3target, 0], coordinates[edge3target, 1]); // add three edges moveQuality += evaluator.CalculateDistance(coordinates[edge3source, 0], coordinates[edge3source, 1], coordinates[edge1target, 0], coordinates[edge1target, 1]); moveQuality += evaluator.CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1], coordinates[edge3target, 0], coordinates[edge3target, 1]); moveQuality += evaluator.CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1], coordinates[edge2target, 0], coordinates[edge2target, 1]); return(moveQuality); }
public static double EvaluateByDistanceMatrix(Permutation permutation, TranslocationMove move, DistanceMatrix distanceMatrix) { if (move.Index1 == move.Index3 || move.Index2 == permutation.Length - 1 && move.Index3 == 0 || move.Index1 == 0 && move.Index3 == permutation.Length - 1 - move.Index2) { return(0); } int edge1source = permutation.GetCircular(move.Index1 - 1); int edge1target = permutation[move.Index1]; int edge2source = permutation[move.Index2]; int edge2target = permutation.GetCircular(move.Index2 + 1); int edge3source, edge3target; if (move.Index3 > move.Index1) { edge3source = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1); edge3target = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1 + 1); } else { edge3source = permutation.GetCircular(move.Index3 - 1); edge3target = permutation[move.Index3]; } double moveQuality = 0; // remove three edges moveQuality -= distanceMatrix[edge1source, edge1target]; moveQuality -= distanceMatrix[edge2source, edge2target]; moveQuality -= distanceMatrix[edge3source, edge3target]; // add three edges moveQuality += distanceMatrix[edge3source, edge1target]; moveQuality += distanceMatrix[edge2source, edge3target]; moveQuality += distanceMatrix[edge1source, edge2target]; return(moveQuality); }
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); }