/// <summary> /// Moves an randomly chosen element in the specified <paramref name="permutation"/> array /// to another randomly generated position. /// </summary> /// <param name="random">The random number generator.</param> /// <param name="permutation">The permutation to manipulate.</param> public static void Apply(IRandom random, Permutation permutation) { Permutation original = (Permutation)permutation.Clone(); int cutIndex, insertIndex, number; cutIndex = random.Next(original.Length); insertIndex = random.Next(original.Length); number = original[cutIndex]; int i = 0; // index in new permutation int j = 0; // index in old permutation while (i < original.Length) { if (j == cutIndex) { j++; } if (i == insertIndex) { permutation[i] = number; i++; } if ((i < original.Length) && (j < original.Length)) { permutation[i] = original[j]; i++; j++; } } }
/// <summary> /// Moves an randomly chosen element in the specified <paramref name="permutation"/> array /// to another randomly generated position. /// </summary> /// <param name="random">The random number generator.</param> /// <param name="permutation">The permutation to manipulate.</param> public static void Apply(IRandom random, Permutation permutation) { Permutation original = (Permutation)permutation.Clone(); int cutIndex, insertIndex, number; cutIndex = random.Next(original.Length); insertIndex = random.Next(original.Length); number = original[cutIndex]; int i = 0; // index in new permutation int j = 0; // index in old permutation while (i < original.Length) { if (j == cutIndex) { j++; } if (i == insertIndex) { permutation[i] = number; i++; } if ((i < original.Length) && (j < original.Length)) { permutation[i] = original[j]; i++; j++; } } }
private static void ExchangeSubsequences(Permutation p1, int index1, Permutation p2, int index2, int subSequenceLength) { var aux = (Permutation)p1.Clone(); for (int i = 0; i < subSequenceLength; i++) { p1[i + index1] = p2[i + index2]; p2[i + index2] = aux[i + index1]; } }
public static void Apply(Permutation permutation, int breakPoint1, int breakPoint2, int insertPoint) { Permutation original = (Permutation)permutation.Clone(); int i = 0; // index in new permutation int j = 0; // index in old permutation while (i < original.Length) { if (i == insertPoint) // copy translocated area { for (int k = breakPoint1; k <= breakPoint2; k++) { permutation[i] = original[k]; i++; } } if (j == breakPoint1) // skip area between breakpoints { j = breakPoint2 + 1; } if ((i < original.Length) && (j < original.Length)) { permutation[i] = original[j]; i++; j++; } } }
/// <summary> /// Moves a randomly chosen interval of elements to another (randomly chosen) position in the given /// <paramref name="permutation"/> array and reverses it. /// </summary> /// <param name="random">The random number generator.</param> /// <param name="permutation">The permutation array to manipulate.</param> public static void Apply(IRandom random, Permutation permutation) { Permutation original = (Permutation)permutation.Clone(); int breakPoint1, breakPoint2, insertPoint, insertPointLimit; breakPoint1 = random.Next(original.Length - 1); breakPoint2 = random.Next(breakPoint1 + 1, original.Length); insertPointLimit = original.Length - breakPoint2 + breakPoint1 - 1; // get insertion point in remaining part if (insertPointLimit > 0) insertPoint = random.Next(insertPointLimit); else insertPoint = 0; int i = 0; // index in new permutation int j = 0; // index in old permutation while (i < original.Length) { if (i == insertPoint) { // copy translocated area for (int k = breakPoint2; k >= breakPoint1; k--) { permutation[i] = original[k]; i++; } } if (j == breakPoint1) { // skip area between breakpoints j = breakPoint2 + 1; } if ((i < original.Length) && (j < original.Length)) { permutation[i] = original[j]; i++; j++; } } }
public static void Apply(Permutation permutation, int startIndex, int[] scrambleArray) { Permutation original = (Permutation)permutation.Clone(); for (int i = 0; i < scrambleArray.Length; i++) // scramble permutation between breakpoints { permutation[startIndex + i] = original[startIndex + scrambleArray[i]]; } }
/// <summary> /// Moves a randomly chosen interval of elements to another (randomly chosen) position in the given /// <paramref name="permutation"/> array and reverses it. /// </summary> /// <param name="random">The random number generator.</param> /// <param name="permutation">The permutation array to manipulate.</param> public static void Apply(IRandom random, Permutation permutation) { Permutation original = (Permutation)permutation.Clone(); int breakPoint1, breakPoint2, insertPoint, insertPointLimit; breakPoint1 = random.Next(original.Length - 1); breakPoint2 = random.Next(breakPoint1 + 1, original.Length); insertPointLimit = original.Length - breakPoint2 + breakPoint1 - 1; // get insertion point in remaining part if (insertPointLimit > 0) { insertPoint = random.Next(insertPointLimit); } else { insertPoint = 0; } int i = 0; // index in new permutation int j = 0; // index in old permutation while (i < original.Length) { if (i == insertPoint) // copy translocated area { for (int k = breakPoint2; k >= breakPoint1; k--) { permutation[i] = original[k]; i++; } } if (j == breakPoint1) // skip area between breakpoints { j = breakPoint2 + 1; } if ((i < original.Length) && (j < original.Length)) { permutation[i] = original[j]; i++; j++; } } }
public static void Apply(Permutation permutation, int breakPoint1, int breakPoint2, int insertPoint) { Permutation original = (Permutation)permutation.Clone(); int i = 0; // index in new permutation int j = 0; // index in old permutation while (i < original.Length) { if (i == insertPoint) { // copy translocated area for (int k = breakPoint1; k <= breakPoint2; k++) { permutation[i] = original[k]; i++; } } if (j == breakPoint1) { // skip area between breakpoints j = breakPoint2 + 1; } if ((i < original.Length) && (j < original.Length)) { permutation[i] = original[j]; i++; j++; } } }
public static void Apply(Permutation permutation, int startIndex, int[] scrambleArray) { Permutation original = (Permutation)permutation.Clone(); for (int i = 0; i < scrambleArray.Length; i++) { // scramble permutation between breakpoints permutation[startIndex + i] = original[startIndex + scrambleArray[i]]; } }
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 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; }