// Is not threadsafe // Changes order from: {0 -> .. -> i} -> {i+1 -> .. -> k} -> {k+1 -> .. -> j} -> {j+1 -> ..end} // To a random new combination of the sections, with {m -> .. -> n} being a section (m != 0, n != end) // Sections CAN be reversed, so there are 3 feasible options: // X) Reverse {i+1 -> k}, Keep {k+1 ->j} -> 2Opt // X) Keep {i+1 -> k}, Reverse {k+1 ->j} -> 2Opt // X) Reverse {i+1 -> k} and {k+1 ->j} -> 2*2Opt // 1) Swap them // 2) Swap them, but Reverse {k+1 ->j} // 3) Swap them, but Reverse {i+1 ->k} // X) Swap them, and Reverse {i+1 ->k} and {k+1 ->j} -> 2Opt // X) Do nothing -> Kinda pointless, eh? // The first and last sections are still in their original place public RouteSim Opt_3_Swap(int i, int k, int j, int variation) { Route newRoute = new Route (this.GarbageTruck, this.DayId); //LinkedList<RouteStop> newRoute = new LinkedList<RouteStop>(); Order order; // Part 1 is normal (from begin to first node to swap) for (int pos = 0; pos < i; pos++) { order = new Order (this.Orders.ElementAt(pos).Order.OrderID, this.Orders.ElementAt(pos).Order.LoadTime, this.Orders.ElementAt(pos).Order.VolumePerContainer, this.Orders.ElementAt(pos).Order.ContainerAmt, this.Orders.ElementAt(pos).Order.Frequency, this.Orders.ElementAt(pos).Order.X, this.Orders.ElementAt(pos).Order.Y, this.Orders.ElementAt(pos).Order.MatrixID); newRoute = newRoute.AddOrder (order).getRoute(); } // Easy // Now part 2 and 3: switch (variation) { case 0: // Swap the sections for (int pos = k; pos < j; pos++) { order = new Order (this.Orders.ElementAt (pos).Order.OrderID, this.Orders.ElementAt (pos).Order.LoadTime, this.Orders.ElementAt (pos).Order.VolumePerContainer, this.Orders.ElementAt (pos).Order.ContainerAmt, this.Orders.ElementAt (pos).Order.Frequency, this.Orders.ElementAt (pos).Order.X, this.Orders.ElementAt (pos).Order.Y, this.Orders.ElementAt (pos).Order.MatrixID); newRoute = newRoute.AddOrder (order).getRoute (); } for (int pos = i; pos < k; pos++) { order = new Order (this.Orders.ElementAt (pos).Order.OrderID, this.Orders.ElementAt (pos).Order.LoadTime, this.Orders.ElementAt (pos).Order.VolumePerContainer, this.Orders.ElementAt (pos).Order.ContainerAmt, this.Orders.ElementAt (pos).Order.Frequency, this.Orders.ElementAt (pos).Order.X, this.Orders.ElementAt (pos).Order.Y, this.Orders.ElementAt (pos).Order.MatrixID); newRoute = newRoute.AddOrder (order).getRoute (); } break; case 1: // Swap the sections reverse latter (now the first one) for (int pos = j - 1; pos >= k; pos--){ order = new Order (this.Orders.ElementAt (pos).Order.OrderID, this.Orders.ElementAt (pos).Order.LoadTime, this.Orders.ElementAt (pos).Order.VolumePerContainer, this.Orders.ElementAt (pos).Order.ContainerAmt, this.Orders.ElementAt (pos).Order.Frequency, this.Orders.ElementAt (pos).Order.X, this.Orders.ElementAt (pos).Order.Y, this.Orders.ElementAt (pos).Order.MatrixID); newRoute = newRoute.AddOrder (order).getRoute (); } for (int pos = i; pos < k; pos++){ order = new Order (this.Orders.ElementAt (pos).Order.OrderID, this.Orders.ElementAt (pos).Order.LoadTime, this.Orders.ElementAt (pos).Order.VolumePerContainer, this.Orders.ElementAt (pos).Order.ContainerAmt, this.Orders.ElementAt (pos).Order.Frequency, this.Orders.ElementAt (pos).Order.X, this.Orders.ElementAt (pos).Order.Y, this.Orders.ElementAt (pos).Order.MatrixID); newRoute = newRoute.AddOrder (order).getRoute (); } // What is the diff in travel time etc? // time -= {i -> i+1} + {k -> k+1} + {k+1 -> .. -> j} + {j -> j+1} // time += {i -> j} + {k+1-> i+1} + {j -> .. -> k+1} + {k+1 -> j+1} break; case 2: // Swap the sections reverse former (now the second one) for (int pos = k; pos < j; pos++){ order = new Order (this.Orders.ElementAt (pos).Order.OrderID, this.Orders.ElementAt (pos).Order.LoadTime, this.Orders.ElementAt (pos).Order.VolumePerContainer, this.Orders.ElementAt (pos).Order.ContainerAmt, this.Orders.ElementAt (pos).Order.Frequency, this.Orders.ElementAt (pos).Order.X, this.Orders.ElementAt (pos).Order.Y, this.Orders.ElementAt (pos).Order.MatrixID); newRoute = newRoute.AddOrder (order).getRoute (); } for (int pos = k - 1; pos >= i; pos--){ order = new Order (this.Orders.ElementAt (pos).Order.OrderID, this.Orders.ElementAt (pos).Order.LoadTime, this.Orders.ElementAt (pos).Order.VolumePerContainer, this.Orders.ElementAt (pos).Order.ContainerAmt, this.Orders.ElementAt (pos).Order.Frequency, this.Orders.ElementAt (pos).Order.X, this.Orders.ElementAt (pos).Order.Y, this.Orders.ElementAt (pos).Order.MatrixID); newRoute = newRoute.AddOrder (order).getRoute (); } break; } // Lastly part 4: for (int pos = j; pos < this.Orders.Count; pos++){ order = new Order (this.Orders.ElementAt (pos).Order.OrderID, this.Orders.ElementAt (pos).Order.LoadTime, this.Orders.ElementAt (pos).Order.VolumePerContainer, this.Orders.ElementAt (pos).Order.ContainerAmt, this.Orders.ElementAt (pos).Order.Frequency, this.Orders.ElementAt (pos).Order.X, this.Orders.ElementAt (pos).Order.Y, this.Orders.ElementAt (pos).Order.MatrixID); newRoute = newRoute.AddOrder (order).getRoute (); } RouteSim result = new RouteSim (); result.getRoute = () => { return newRoute; }; result.time = newRoute.EnRouteTime; return result; }
// Is not threadsafe /// <summary> /// /// </summary> /// <param name="i"></param> /// <param name="k"> should be between 0 and Orders.length - 2 (inclusive) </param> public RouteSim Opt_2_Swap(int i, int k) { Route newRoute = new Route (this.GarbageTruck, this.DayId); /*LinkedList<RouteStop> newRoute = new LinkedList<RouteStop>(); int changeTime = 0; changeTime -= Program.afstandenMatrix[oldRoute[i].Order.MatrixID, oldRoute[i + 1].Order.MatrixID].TravelTime + Program.afstandenMatrix[oldRoute[k].Order.MatrixID, oldRoute[k + 1].Order.MatrixID].TravelTime; changeTime += Program.afstandenMatrix[oldRoute[i].Order.MatrixID, oldRoute[k + 1].Order.MatrixID].TravelTime + Program.afstandenMatrix[oldRoute[i + 1].Order.MatrixID, oldRoute[k + 1].Order.MatrixID].TravelTime;*/ // Time -= {i -> i+1} + {k -> k+1} + {i+1 -> .. -> k} // Time += {i -> k+1} + {i+1 -> k+1} + { k -> .. -> i+1} Order order; // Part 1 is normal (from begin to first node to swap) for (int j = 0; j < i; j++) { order = new Order (this.Orders.ElementAt(j).Order.OrderID, this.Orders.ElementAt(j).Order.LoadTime, this.Orders.ElementAt(j).Order.VolumePerContainer, this.Orders.ElementAt(j).Order.ContainerAmt, this.Orders.ElementAt(j).Order.Frequency, this.Orders.ElementAt(j).Order.X, this.Orders.ElementAt(j).Order.Y, this.Orders.ElementAt(j).Order.MatrixID); newRoute = newRoute.AddOrder (order).getRoute(); } // Part 2, reverse {i+1 -> .. -> k} for (int j = k - 1; j >= i; j--) { order = new Order (this.Orders.ElementAt(j).Order.OrderID, this.Orders.ElementAt(j).Order.LoadTime, this.Orders.ElementAt(j).Order.VolumePerContainer, this.Orders.ElementAt(j).Order.ContainerAmt, this.Orders.ElementAt(j).Order.Frequency, this.Orders.ElementAt(j).Order.X, this.Orders.ElementAt(j).Order.Y, this.Orders.ElementAt(j).Order.MatrixID); newRoute = newRoute.AddOrder (order).getRoute(); /* // Verwijder de oude tijd changeTime -= Program.afstandenMatrix[oldRoute[j - 1].Order.MatrixID, oldRoute[j].Order.MatrixID].TravelTime; // Voeg de nieuwe tijd toe changeTime += Program.afstandenMatrix[oldRoute[j].Order.MatrixID, oldRoute[j - 1].Order.MatrixID].TravelTime;*/ } // Part 3, the rest for (int j = k; j < this.Orders.Count; j++) { order = new Order (this.Orders.ElementAt(j).Order.OrderID, this.Orders.ElementAt(j).Order.LoadTime, this.Orders.ElementAt(j).Order.VolumePerContainer, this.Orders.ElementAt(j).Order.ContainerAmt, this.Orders.ElementAt(j).Order.Frequency, this.Orders.ElementAt(j).Order.X, this.Orders.ElementAt(j).Order.Y, this.Orders.ElementAt(j).Order.MatrixID); newRoute = newRoute.AddOrder (order).getRoute(); } //int EnRouteTime = this.EnRouteTime + changeTime; RouteSim result = new RouteSim (); //Route obj = this; result.getRoute = () => { return newRoute; }; result.time = newRoute.EnRouteTime; return result; }