public static Order[] LoadOrders() { string dir = Directory.GetCurrentDirectory(); string filename = "Orderbestand.txt"; string[] orderStrings = File.ReadAllLines(Path.Combine(dir, "..", "..", filename)); Order[] orders = new Order[orderStrings.Length-1]; for (int i = 1; i < orderStrings.Length; i++) orders[i-1] = parseOrderString(orderStrings[i]); return orders; }
public Order(Order order) { this.VolumePerContainer = order.VolumePerContainer; this.ContainerAmt = order.ContainerAmt; this.CompressedVolume = order.CompressedVolume; this.Frequency = order.Frequency; this.Routes = order.Routes; this.X = order.X; this.Y = order.Y; this.MatrixID = order.MatrixID; this.OrderID = order.OrderID; this.LoadTime = order.LoadTime; }
// Add an order to the list // Keep in mind: The Travel Time is in seconds! public RouteSim AddOrder(Order destination, int location = -1) { RouteSim result = new RouteSim (); Route obj = this; if (this.Orders.Count == 0) { if (this.Clearings.Count == 0) { this.Clearings.AddLast(new GarbageStop ()); } result.getRoute = () => { RouteStop stop = new RouteStop(); stop.Order = destination; stop.Node = obj.Orders.AddLast(stop); stop.NextClearing = obj.Clearings.Last; stop.NextClearing.Value.Amount = stop.Order.CompressedVolume; stop.NextClearing.Value.Last = stop.Node; obj.EnRouteTime = Program.afstandenMatrix [287, destination.MatrixID].TravelTime + destination.LoadTime + Program.afstandenMatrix [destination.MatrixID, 287].TravelTime + 1800; return obj; }; result.time = Program.afstandenMatrix [287, destination.MatrixID].TravelTime + destination.LoadTime + Program.afstandenMatrix [destination.MatrixID, 287].TravelTime + 1800; if (result.time > dayTimeSec) { throw new OverflowException ("Too much!"); } return result; } if (location == -1) { Random rnd = new Random (); location = rnd.Next(this.Orders.Count); } RouteStop next = this.Orders.ElementAt(location); int prevID; if (next.Node.Previous != null) { prevID = next.Node.Previous.Value.Order.MatrixID; } else { prevID = 287; // The garbage disposal location } int curID = destination.MatrixID; int nextID = next.Order.MatrixID; float EnRouteTime = this.EnRouteTime; EnRouteTime -= Program.afstandenMatrix [prevID, nextID].TravelTime; EnRouteTime += Program.afstandenMatrix [prevID, curID].TravelTime; EnRouteTime += Program.afstandenMatrix [curID, nextID].TravelTime; EnRouteTime += destination.LoadTime; var nextClearing = next.NextClearing; RouteStop stop2 = new RouteStop(); stop2.Order = destination; stop2.Node = obj.Orders.AddBefore (next.Node, stop2); stop2.NextClearing = nextClearing; var fixSim = FixClearings (nextClearing, destination.CompressedVolume, false); obj.Orders.Remove (stop2.Node); EnRouteTime += fixSim.delta; result.getRoute = () => { //fixSim.getRoute(); // Get the new time and distance required obj.EnRouteTime = EnRouteTime; stop2.Node = obj.Orders.AddBefore (next.Node, stop2); obj = fixSim.getRoute(); return obj; }; result.time = EnRouteTime; if (result.time > dayTimeSec) { throw new OverflowException ("Too much!"); } return result; }
// O(n) time to remove an element at position x public RouteSim RemoveOrder(Order order) { LinkedListNode<RouteStop> cur = this.Orders.First; while (cur != this.Orders.Last) { if (cur.Value.Order.OrderID == order.OrderID) { break; } cur = cur.Next; } if (cur.Value.Order.OrderID != order.OrderID) { throw new ArgumentOutOfRangeException (); } return this.RemoveOrder (cur.Value); }
// 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; }