/// <summary> /// Test removing adding every customer at every position. /// </summary> public void DoTestAddRemoveComplete() { // create a new empty route. const int count = 10; for (int customerToRemove = 0; customerToRemove < count; customerToRemove++) { for (int customerToPlaceAfter = 0; customerToPlaceAfter < count; customerToPlaceAfter++) { if (customerToRemove != customerToPlaceAfter) { IRoute route = this.BuildRoute(true); if (route != null) { // this part needs testing. for (int customer = 0; customer < count; customer++) { route.InsertAfter(customer - 1, customer); //route.InsertAfterAndRemove(customer - 1, customer, -1); } route.Remove(customerToRemove); route.InsertAfter(customerToPlaceAfter, customerToRemove); //route.InsertAfterAndRemove(customer_to_place_after, customer_to_remove, -1); Assert.IsTrue(route.Contains(customerToPlaceAfter, customerToRemove)); Assert.AreEqual(count, route.Count); var customersInRoute = new HashSet <int>(route); Assert.AreEqual(customersInRoute.Count, route.Count); } } } } }
/// <summary> /// Removes a given customer. /// </summary> /// <param name="customer"></param> /// <returns></returns> public bool Remove(int customer) { if (customer == 0) { throw new Exception("Cannot remove depot from depot routes."); } return(_route.Remove(customer)); }
/// <summary> /// Tests adding customers. /// </summary> public void DoTestRemove() { IMultiRoute multiRoute = this.BuildRoute(true); Assert.AreEqual(0, multiRoute.Count); int count = 10; int routes = 3; // test with initializing the routes empty. var customersPerRoute = new List <List <int> >(); Assert.AreEqual(0, multiRoute.Count); for (int routeIdx = 0; routeIdx < routes; routeIdx++) { customersPerRoute.Add(new List <int>()); int customerStart = (routeIdx * count); IRoute route = multiRoute.Add(); for (int customer = customerStart; customer < customerStart + count; customer++) { customersPerRoute[routeIdx].Add(customer); route.InsertAfter(customer - 1, customer); //route.InsertAfterAndRemove(customer - 1, customer, -1); } } // remove all the customers. while (customersPerRoute.Count > 0) { int routeIdx = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(customersPerRoute.Count); int customerIdx = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(customersPerRoute[routeIdx].Count); int customer = customersPerRoute[routeIdx][customerIdx]; customersPerRoute[routeIdx].RemoveAt(customerIdx); IRoute route = multiRoute.Route(routeIdx); route.Remove(customer); Assert.AreEqual(customersPerRoute[routeIdx].Count, route.Count); Assert.AreEqual(customersPerRoute[routeIdx].Count == 0, route.IsEmpty); Assert.AreEqual(true, route.IsRound); Assert.AreEqual(route.First, route.Last); if (customersPerRoute[routeIdx].Count == 0) { customersPerRoute.RemoveAt(routeIdx); multiRoute.Remove(routeIdx); } } }
/// <summary> /// Tries to improve the existing route using CI and return true if succesful. /// </summary> /// <param name="problem"></param> /// <param name="route"></param> /// <param name="difference"></param> /// <returns></returns> public bool Improve(IProblemWeights problem, IRoute route, out double difference) { bool improvement = false; difference = 0; if (route.Count > 3) { // loop over all customers and try cheapest insertion. for (int customer = 0; customer < problem.Size; customer++) { //string route_string = route.ToString(); //IRoute previous = route.Clone() as IRoute; if (route.Contains(customer)) { // remove customer and keep position. int next = route.GetNeigbours(customer)[0]; route.Remove(customer); // insert again. ArbitraryInsertionSolver.InsertOne(problem, route, customer, out difference); if (!route.IsValid()) { throw new Exception(); } if (route.GetNeigbours(customer)[0] != next && difference < 0) { // another customer was found as the best, improvement is succesful. improvement = true; break; } } } } return(improvement); }
/// <summary> /// Test removing customers. /// </summary> public void DoTestRemove() { // create a new empty route. const int count = 100; IRoute route = this.BuildRoute(0, true); var customers = new List <int>(); if (route != null) { // this part needs testing! customers.Add(0); for (int customer = 1; customer < count; customer++) { route.InsertAfter(customer - 1, customer); //route.InsertAfterAndRemove(customer - 1, customer, -1); customers.Add(customer); } // remove customers. while (customers.Count > 0) { int customerIdx = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate( customers.Count); int customer = customers[customerIdx]; customers.RemoveAt(customerIdx); route.Remove(customer); Assert.AreEqual(customers.Count, route.Count); Assert.AreEqual(customers.Count == 0, route.IsEmpty); Assert.AreEqual(true, route.IsRound); Assert.AreEqual(route.Last, route.First); } } route = this.BuildRoute(true); customers = new List <int>(); if (route != null) { // this part needs testing! for (int customer = 0; customer < count; customer++) { route.InsertAfter(customer - 1, customer); //route.InsertAfterAndRemove(customer - 1, customer, -1); customers.Add(customer); } // remove customers. while (customers.Count > 0) { int customerIdx = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate( customers.Count); int customer = customers[customerIdx]; customers.RemoveAt(customerIdx); route.Remove(customer); Assert.AreEqual(customers.Count, route.Count); Assert.AreEqual(customers.Count == 0, route.IsEmpty); Assert.AreEqual(true, route.IsRound); Assert.AreEqual(route.Last, route.First); } } }
/// <summary> /// Applies a local search strategy. /// </summary> /// <param name="problem"></param> /// <param name="route"></param> /// <returns></returns> public static void CalculateRePlaceOptHelper( IProblemWeights problem, IRoute route) { //bool improvement = true; //while (improvement) //{ //// reset improvement flag. //improvement = false; // try re-placement of one customer. int before = -1; //int after = -1; int found_customer = -1; // loop over all customers and try to place it better. HashSet <int> customers_to_place = new HashSet <int>(route); foreach (int customer_to_place in customers_to_place) { // find the best place. double current_cost = -1; double other_cost = double.MaxValue; int previous_before = -1; int previous = -1; foreach (int customer in route) { if (previous >= 0 && previous_before >= 0) { if (previous == customer_to_place) { current_cost = problem.Weight(previous_before, previous) + problem.Weight(previous, customer); } else if (previous_before != customer_to_place && customer != customer_to_place) { // calculate the cost. double cost = problem.Weight(previous_before, customer_to_place) + problem.Weight(customer_to_place, previous); if (cost < other_cost) { other_cost = cost; before = previous_before; //after = previous; found_customer = customer; } } } previous_before = previous; previous = customer; } // determine if the cost is better. if (current_cost > other_cost) { // the current cost is better. route.Remove(found_customer); //route.InsertAfterAndRemove(before, found_customer, after); route.InsertAfter(before, found_customer); break; } else { // current cost is not better. before = -1; //after = -1; found_customer = -1; } } //if (found_customer >= 0) //{ // a found customer. // improvement = true; //} //} }
/// <summary> /// Tries to improve the existing route using CI and return true if succesful. /// </summary> /// <param name="problem"></param> /// <param name="route"></param> /// <param name="difference"></param> /// <returns></returns> public bool Improve(IProblemWeights problem, IRoute route, out double difference) { bool improvement = false; difference = 0; if (route.Count > 3) { // loop over all customers and try cheapest insertion. for (int customer = 0; customer < problem.Size; customer++) { //string route_string = route.ToString(); //IRoute previous = route.Clone() as IRoute; if (route.Contains(customer)) { // remove customer and keep position. int next = route.GetNeigbours(customer)[0]; route.Remove(customer); // insert again. ArbitraryInsertionSolver.InsertOne(problem, route, customer, out difference); if (!route.IsValid()) { throw new Exception(); } if (route.GetNeigbours(customer)[0] != next && difference < 0) { // another customer was found as the best, improvement is succesful. improvement = true; break; } } } } return improvement; }
/// <summary> /// Applies a local search strategy. /// </summary> /// <param name="problem"></param> /// <param name="route"></param> /// <returns></returns> public static void CalculateRePlaceOptHelper( IProblemWeights problem, IRoute route) { //bool improvement = true; //while (improvement) //{ //// reset improvement flag. //improvement = false; // try re-placement of one customer. int before = -1; int after = -1; int found_customer = -1; // loop over all customers and try to place it better. HashSet<int> customers_to_place = new HashSet<int>(route); foreach (int customer_to_place in customers_to_place) { // find the best place. double current_cost = -1; double other_cost = double.MaxValue; int previous_before = -1; int previous = -1; foreach (int customer in route) { if (previous >= 0 && previous_before >= 0) { if (previous == customer_to_place) { current_cost = problem.Weight(previous_before, previous) + problem.Weight(previous, customer); } else if (previous_before != customer_to_place && customer != customer_to_place) { // calculate the cost. double cost = problem.Weight(previous_before, customer_to_place) + problem.Weight(customer_to_place, previous); if (cost < other_cost) { other_cost = cost; before = previous_before; after = previous; found_customer = customer; } } } previous_before = previous; previous = customer; } // determine if the cost is better. if (current_cost > other_cost) { // the current cost is better. route.Remove(found_customer); //route.InsertAfterAndRemove(before, found_customer, after); route.InsertAfter(before, found_customer); break; } else { // current cost is not better. before = -1; after = -1; found_customer = -1; } } //if (found_customer >= 0) //{ // a found customer. // improvement = true; //} //} }