/// <summary> /// Generate the nearest neighbour list. /// </summary> /// <param name="v"></param> /// <returns></returns> public NearestNeighbours10 Get10NearestNeighbours(int v) { if (_neighbours == null) { _neighbours = new NearestNeighbours10[this.Size]; } NearestNeighbours10 result = _neighbours[v]; if (result == null) { SortedDictionary <double, List <int> > neighbours = new SortedDictionary <double, List <int> >(); for (int customer = 0; customer < this.Size; customer++) { if (customer != v) { double weight = this.WeightMatrix[v][customer]; List <int> customers = null; if (!neighbours.TryGetValue(weight, out customers)) { customers = new List <int>(); neighbours.Add(weight, customers); } customers.Add(customer); } } result = new NearestNeighbours10(); foreach (KeyValuePair <double, List <int> > pair in neighbours) { foreach (int customer in pair.Value) { if (result.Count < 10) { if (result.Max < pair.Key) { result.Max = pair.Key; } result.Add(customer); } else { break; } } } _neighbours[v] = result; } return(result); }
/// <summary> /// Tries all 3Opt Moves for the neighbourhood of v_1. /// </summary> /// <param name="problem"></param> /// <param name="weights"></param> /// <param name="route"></param> /// <param name="v1"></param> /// <returns></returns> public bool Try3OptMoves(IProblemWeights problem, double[][] weights, IRoute route, int v1) { // get v_2. int v_2 = route.GetNeigbours(v1)[0]; if (v_2 < 0) { return(false); } IEnumerable <int> between_v_2_v_1 = route.Between(v_2, v1); double weight_1_2 = weights[v1][v_2]; int v_3 = -1; NearestNeighbours10 neighbours = null; if (_nearest_neighbours) { neighbours = problem.Get10NearestNeighbours(v1); } foreach (int v_4 in between_v_2_v_1) { if (v_3 >= 0 && v_3 != v1) { //if (!_nearest_neighbours || // neighbours.Max <= weight_1_4) if (!_nearest_neighbours || neighbours.Contains(v_4)) { double weight_1_4 = weights[v1][v_4]; double weight_1_2_plus_3_4 = weight_1_2 + weights[v_3][v_4]; double[] weights_3 = weights[v_3]; if (this.Try3OptMoves(problem, weights, route, v1, v_2, v_3, weights_3, v_4, weight_1_2_plus_3_4, weight_1_4)) { return(true); } } } v_3 = v_4; } return(false); }
/// <summary> /// Generate the nearest neighbour list. /// </summary> /// <param name="v"></param> /// <returns></returns> public NearestNeighbours10 Get10NearestNeighbours(int v) { if (_neighbours == null) { _neighbours = new NearestNeighbours10[this.Size]; } NearestNeighbours10 result = _neighbours[v]; if (result == null) { SortedDictionary<double, List<int>> neighbours = new SortedDictionary<double, List<int>>(); for (int customer = 0; customer < this.Size; customer++) { if (customer != v) { double weight = this.WeightMatrix[v][customer]; List<int> customers = null; if (!neighbours.TryGetValue(weight, out customers)) { customers = new List<int>(); neighbours.Add(weight, customers); } customers.Add(customer); } } result = new NearestNeighbours10(); foreach (KeyValuePair<double, List<int>> pair in neighbours) { foreach (int customer in pair.Value) { if (result.Count < 10) { if (result.Max < pair.Key) { result.Max = pair.Key; } result.Add(customer); } else { break; } } } _neighbours[v] = result; } return result; }