/// <summary> /// Tries all 3Opt Moves for the neighbourhood of v1. /// </summary> /// <returns></returns> public bool Try3OptMoves(TSProblem problem, float[][] weights, Tour tour, int v1, out float delta) { // get v_2. var v2 = tour.GetNeigbour(v1); if (v2 < 0) { delta = 0; return(false); } var betweenV2V1 = tour.Between(v2, v1); //var weightV1V2 = weights[v1][v2]; var weightV1V2 = weights.WeightWithoutTurns(v1, v2); if (DirectedHelper.ExtractId(v2) == problem.First && !problem.Last.HasValue) { // set to zero if not closed. weightV1V2 = 0; } int v3 = -1; NearestNeighbours neighbours = null; if (_nearestNeighbours) { neighbours = problem.GetNNearestNeighboursForward(10, DirectedHelper.ExtractId(v1)); } foreach (int v4 in betweenV2V1) { if (v3 >= 0 && v3 != v1) { var v4Id = DirectedHelper.ExtractId(v4); if (!_nearestNeighbours || neighbours.Contains(v4Id)) { //var weightV1V4 = weights[v1][v4]; var weightV1V4 = weights.WeightWithoutTurns(v1, v4); //var weightV3V4 = weights[v3][v4]; var weightV3V4 = weights.WeightWithoutTurns(v3, v4); if (v4Id == problem.First && !problem.Last.HasValue) { // set to zero if not closed. weightV1V4 = 0; weightV3V4 = 0; } var weightV1V2PlusV3V4 = weightV1V2 + weightV3V4; //var weightsV3 = weights[v3]; var weightsV3 = weights[DirectedHelper.ExtractDepartureId(v3)]; if (this.Try3OptMoves(problem, weights, tour, v1, v2, v3, weightsV3, v4, weightV1V2PlusV3V4, weightV1V4, out delta)) { return(true); } } } v3 = v4; } delta = 0; return(false); }
/// <summary> /// Generate the nearest neighbour list. /// </summary> /// <returns></returns> public NearestNeighbours GetNNearestNeighboursBackward(int n, int id) { if (_backwardNearestNeighbours == null) { // not there yet, create. _backwardNearestNeighbours = new Dictionary <int, NearestNeighbours[]>(); } NearestNeighbours[] nearestNeighbours = null; if (!_backwardNearestNeighbours.TryGetValue(n, out nearestNeighbours)) { // not found for n, create. nearestNeighbours = new NearestNeighbours[this.Times.Length]; _backwardNearestNeighbours.Add(n, nearestNeighbours); } var result = nearestNeighbours[id]; if (result == null) { // not found, calculate. result = NearestNeighbours.BackwardDirected(this.Times, n, id); nearestNeighbours[id] = result; } return(result); }
/// <summary> /// Generate the nearest neighbour list. /// </summary> /// <returns></returns> public NearestNeighbours GetNNearestNeighboursForward(int n, int customer) { if (_forwardNearestNeighbours == null) { // not there yet, create. _forwardNearestNeighbours = new Dictionary <int, NearestNeighbours[]>(); } NearestNeighbours[] nearestNeighbours = null; if (!_forwardNearestNeighbours.TryGetValue(n, out nearestNeighbours)) { // not found for n, create. nearestNeighbours = new NearestNeighbours[this.Weights.Length]; _forwardNearestNeighbours.Add(n, nearestNeighbours); } var result = nearestNeighbours[customer]; if (result == null) { // not found, calculate. result = NearestNeighbours.Forward(this.Weights, n, customer); nearestNeighbours[customer] = result; } return(result); }