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 Apply(DistanceMatrix distances, Permutation tour) { if (distances == null || distances.Rows == 0 || distances.Columns == 0 || distances.Rows != distances.Columns) throw new InvalidOperationException("TSPDistanceMatrixEvaluator: The distance matrix is empty or not square"); if (tour == null) throw new ArgumentNullException("tour", "TSPDistanceMatrixEvaluator: No tour is given."); Permutation p = tour; double length = 0; for (int i = 0; i < p.Length - 1; i++) length += distances[p[i], p[i + 1]]; length += distances[p[p.Length - 1], p[0]]; return length; }
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 ItemArray<IItem> Apply(IItem initiator, IItem[] guides, DistanceMatrix distances, PercentValue n) { if (!(initiator is Permutation) || guides.Any(x => !(x is Permutation))) throw new ArgumentException("Cannot relink path because some of the provided solutions have the wrong type."); if (n.Value <= 0.0) throw new ArgumentException("RelinkingAccuracy must be greater than 0."); Permutation v1 = initiator.Clone() as Permutation; Permutation[] targets = new Permutation[guides.Length]; Array.Copy(guides, targets, guides.Length); if (targets.Any(x => x.Length != v1.Length)) throw new ArgumentException("At least one solution is of different length."); IList<Permutation> solutions = new List<Permutation>(); for (int i = 0; i < v1.Length; i++) { int currCityIndex = i; int bestCityIndex = (i + 1) % v1.Length; double currDistance = distances[v1[currCityIndex], v1[bestCityIndex]]; // check each guiding solution targets.ToList().ForEach(solution => { // locate current city var node = solution.Select((x, index) => new { Id = x, Index = index }).Single(x => x.Id == v1[currCityIndex]); int pred = solution[(node.Index - 1 + solution.Length) % solution.Length]; int succ = solution[(node.Index + 1) % solution.Length]; // get distances to neighbors var results = new[] { pred, succ }.Select(x => new { Id = x, Distance = distances[x, node.Id] }); var bestCity = results.Where(x => x.Distance < currDistance).OrderBy(x => x.Distance).FirstOrDefault(); if (bestCity != null) { bestCityIndex = v1.Select((x, index) => new { Id = x, Index = index }).Single(x => x.Id == bestCity.Id).Index; currDistance = bestCity.Distance; } }); Invert(v1, currCityIndex + 1, bestCityIndex); solutions.Add(v1.Clone() as Permutation); } IList<IItem> selection = new List<IItem>(); if (solutions.Count > 0) { int noSol = (int)(solutions.Count * n.Value); if (noSol <= 0) noSol++; double stepSize = (double)solutions.Count / (double)noSol; for (int i = 0; i < noSol; i++) selection.Add(solutions.ElementAt((int)((i + 1) * stepSize - stepSize * 0.5))); } return new ItemArray<IItem>(selection); }
private DistanceMatrix(DistanceMatrix original, Cloner cloner) { throw new NotSupportedException("Distance matrices cannot be cloned."); }
protected override double EvaluateByDistanceMatrix(Permutation permutation, DistanceMatrix distanceMatrix) { return EvaluateByDistanceMatrix(permutation, TranslocationMoveParameter.ActualValue, distanceMatrix); }
private DistanceMatrix CalculateDistanceMatrix(DoubleMatrix c) { DistanceMatrix distanceMatrix = new DistanceMatrix(c.Rows, c.Rows); for (int i = 0; i < distanceMatrix.Rows; i++) { for (int j = 0; j < distanceMatrix.Columns; j++) distanceMatrix[i, j] = CalculateDistance(c[i, 0], c[i, 1], c[j, 0], c[j, 1]); } return (DistanceMatrix)distanceMatrix.AsReadOnly(); }
protected abstract double EvaluateByDistanceMatrix(Permutation permutation, DistanceMatrix distanceMatrix);
private DistanceMatrix(DistanceMatrix original, Cloner cloner) { throw new NotSupportedException("Distance matrices cannot be cloned."); }
public static ItemArray <IItem> Apply(IItem initiator, IItem[] guides, DistanceMatrix distances, PercentValue n) { if (!(initiator is Permutation) || guides.Any(x => !(x is Permutation))) { throw new ArgumentException("Cannot relink path because some of the provided solutions have the wrong type."); } if (n.Value <= 0.0) { throw new ArgumentException("RelinkingAccuracy must be greater than 0."); } Permutation v1 = initiator.Clone() as Permutation; Permutation[] targets = new Permutation[guides.Length]; Array.Copy(guides, targets, guides.Length); if (targets.Any(x => x.Length != v1.Length)) { throw new ArgumentException("At least one solution is of different length."); } IList <Permutation> solutions = new List <Permutation>(); for (int i = 0; i < v1.Length; i++) { int currCityIndex = i; int bestCityIndex = (i + 1) % v1.Length; double currDistance = distances[v1[currCityIndex], v1[bestCityIndex]]; // check each guiding solution targets.ToList().ForEach(solution => { // locate current city var node = solution.Select((x, index) => new { Id = x, Index = index }).Single(x => x.Id == v1[currCityIndex]); int pred = solution[(node.Index - 1 + solution.Length) % solution.Length]; int succ = solution[(node.Index + 1) % solution.Length]; // get distances to neighbors var results = new[] { pred, succ }.Select(x => new { Id = x, Distance = distances[x, node.Id] }); var bestCity = results.Where(x => x.Distance < currDistance).OrderBy(x => x.Distance).FirstOrDefault(); if (bestCity != null) { bestCityIndex = v1.Select((x, index) => new { Id = x, Index = index }).Single(x => x.Id == bestCity.Id).Index; currDistance = bestCity.Distance; } }); Invert(v1, currCityIndex + 1, bestCityIndex); solutions.Add(v1.Clone() as Permutation); } IList <IItem> selection = new List <IItem>(); if (solutions.Count > 0) { int noSol = (int)(solutions.Count * n.Value); if (noSol <= 0) { noSol++; } double stepSize = (double)solutions.Count / (double)noSol; for (int i = 0; i < noSol; i++) { selection.Add(solutions.ElementAt((int)((i + 1) * stepSize - stepSize * 0.5))); } } return(new ItemArray <IItem>(selection)); }
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); }
protected override double EvaluateByDistanceMatrix(Permutation permutation, DistanceMatrix distanceMatrix) { return(EvaluateByDistanceMatrix(permutation, InversionMoveParameter.ActualValue, distanceMatrix)); }
protected abstract double EvaluateByDistanceMatrix(Permutation permutation, DistanceMatrix distanceMatrix);
public sealed override IOperation InstrumentedApply() { if (UseDistanceMatrixParameter.ActualValue.Value) { Permutation p = PermutationParameter.ActualValue; DistanceMatrix dm = DistanceMatrixParameter.ActualValue; if (dm == null) { // calculate distance matrix lock (locker) { dm = DistanceMatrixParameter.ActualValue; if (dm == null) { // check again to avoid race condition DoubleMatrix c = CoordinatesParameter.ActualValue; if (c == null) throw new InvalidOperationException("Neither a distance matrix nor coordinates were given."); dm = new DistanceMatrix(c.Rows, c.Rows); for (int i = 0; i < dm.Rows; i++) { for (int j = 0; j < dm.Columns; j++) dm[i, j] = CalculateDistance(c[i, 0], c[i, 1], c[j, 0], c[j, 1]); } DistanceMatrixParameter.ActualValue = (DistanceMatrix)dm.AsReadOnly(); } } } double length = 0; for (int i = 0; i < p.Length - 1; i++) length += dm[p[i], p[i + 1]]; length += dm[p[p.Length - 1], p[0]]; QualityParameter.ActualValue = new DoubleValue(length); } else { Permutation p = PermutationParameter.ActualValue; DoubleMatrix c = CoordinatesParameter.ActualValue; if (c == null) throw new InvalidOperationException("No coordinates were given."); double length = 0; for (int i = 0; i < p.Length - 1; i++) length += CalculateDistance(c[p[i], 0], c[p[i], 1], c[p[i + 1], 0], c[p[i + 1], 1]); length += CalculateDistance(c[p[p.Length - 1], 0], c[p[p.Length - 1], 1], c[p[0], 0], c[p[0], 1]); QualityParameter.ActualValue = new DoubleValue(length); } return base.InstrumentedApply(); }
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); }