/// <summary> /// Replaces some edges with a list of other edges. /// </summary> /// <param name="route"></param> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> private FixedSymmetricRoute Replace(FixedSymmetricRoute route, EdgeList x, EdgeList y) { FixedSymmetricRoute route_new = route.Clone() as FixedSymmetricRoute; for (int idx = 0; idx < x.Count; idx++) { Edge x_edge = x[idx]; route_new.Remove(x_edge.From, x_edge.To); } for (int idx = 0; idx < x.Count; idx++) { Edge y_edge = y[idx]; route_new.Add(y_edge.From, y_edge.To); } //if (!route_new.IsValidNew() && route_new.IsValid()) //{ // Debug.Write(string.Empty); //} //else //{ // Debug.Write(string.Empty); //} return(route_new); }
///// <summary> ///// A naive selection method. ///// </summary> ///// <param name="problem"></param> ///// <param name="route"></param> ///// <param name="X"></param> ///// <param name="Y"></param> ///// <param name="x"></param> ///// <param name="y"></param> ///// <param name="exceptions"></param> ///// <returns></returns> //private int? SelectY( // IProblem problem, FixedSymmetricRoute route, EdgeSet X, EdgeSet Y, EdgeList x, EdgeList y, HashSet<int> exceptions) //{ // int from = x.Last.To; // // search an edge with weight smaller than g. // // VERY NAIVE METHOD! // List<int> test_list = new List<int>(); // float best_extra = float.MaxValue; // int? best_customer = null; // for (int other_customer = 0; other_customer < problem.Size; other_customer++) // { // if (other_customer != from && exceptions != null && !exceptions.Contains(other_customer)) // { // if (!x.Contains(from, other_customer) // && !route.Contains(from, other_customer)) // //&& !Y.Contains(from, other_customer)) // //&& !X.Contains(from, other_customer)) // { // float extra = problem.Weight(from, other_customer); // if (y.Weight + extra < x.Weight) // { // if (x.Count < 3) // { // best_customer = other_customer; // best_extra = extra; // break; // } // test_list.Add(other_customer); // if (extra < best_extra) // { // best_customer = other_customer; // best_extra = extra; // if (x.Count < 3) // { // break; // } // } // } // } // } // } // return best_customer; //} /// <summary> /// Selects with special priority. /// </summary> /// <param name="problem"></param> /// <param name="route"></param> /// <param name="X"></param> /// <param name="Y"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="exceptions"></param> /// <returns></returns> private int? SelectY( IProblem problem, FixedSymmetricRoute route, EdgeSet X, EdgeSet Y, EdgeList x, EdgeList y, HashSet<int> exceptions) { int from = x.Last.To; // search an edge with weight smaller than g. //float best_priority = float.MinValue; int? best_customer = null; foreach (Edge edge in _sparse_set.GetFor(from)) { if (exceptions == null || !exceptions.Contains(edge.To)) { if (edge.From != edge.To && !x.Contains(edge) && !y.Contains(edge) && !route.Contains(edge.From, edge.To) //&& !Y.Contains(from, other_customer)) && !X.Contains(from, edge.To)) { double extra = edge.Weight; if (y.Weight + extra < x.Weight) { //if (x.Count < 2) //{ best_customer = edge.To; break; //} //// calculate priority. //int? x_other = this.SelectX(problem, route, X, Y, x, edge.To, null); //float priority = float.MinValue; //if (x_other != null) //{ // float x_other_weight = problem.Weight(edge.To, x_other.Value); // priority = x_other_weight - extra; //} //if (priority > best_priority) //{ // best_customer = edge.To; // best_priority = priority; //} } } } } return best_customer; }
private int? SelectX( IProblem problem, FixedSymmetricRoute route, EdgeSet X, EdgeSet Y, EdgeList x, int customer, HashSet<int> exceptions) { // select the only two edges that have the given customer in the given route. int[] neigbours = route.GetNeigbours(customer); int previous = neigbours[0]; int next = neigbours[1]; int? best_neighour = null; double best_weight = double.MinValue; if (previous > 0 && (exceptions == null || !exceptions.Contains(previous)) && !x.Contains(customer, previous)) //&& !X.Contains(customer, previous)) //&& !Y.Contains(customer, previous)) { //if (x.Count > 2) //{ double weight = problem.Weight(customer, previous); if (weight > best_weight) { best_neighour = previous; best_weight = weight; } //} //else //{ return previous; //} } if (next > 0 && (exceptions == null || !exceptions.Contains(next)) && !x.Contains(customer, next)) //&& !X.Contains(customer, previous)) //&& !Y.Contains(customer, previous)) { //if (x.Count > 2) //{ double weight = problem.Weight(customer, next); if (weight > best_weight) { best_neighour = next; best_weight = weight; } //} //else //{ return next; //} } return best_neighour; }
/// <summary> /// Replaces some edges with a list of other edges. /// </summary> /// <param name="route"></param> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> private FixedSymmetricRoute Replace(FixedSymmetricRoute route, EdgeList x, EdgeList y) { FixedSymmetricRoute route_new = route.Clone() as FixedSymmetricRoute; for (int idx = 0; idx < x.Count; idx++) { Edge x_edge = x[idx]; route_new.Remove(x_edge.From, x_edge.To); } for (int idx = 0; idx < x.Count; idx++) { Edge y_edge = y[idx]; route_new.Add(y_edge.From, y_edge.To); } //if (!route_new.IsValidNew() && route_new.IsValid()) //{ // Debug.Write(string.Empty); //} //else //{ // Debug.Write(string.Empty); //} return route_new; }
private RouteFound AfterSelectt5(IProblem problem, RouteFound route, EdgeSet X, EdgeSet Y, EdgeList x, EdgeList y) { int t_1 = x[0].From; int t_2i_min_1 = y[y.Count - 1].To; // try and find a better route with t_1. RouteFound new_route = new RouteFound() { RouteWeight = float.MaxValue, Route = null }; HashSet<int> exceptions = new HashSet<int>(); int? result = this.SelectX(problem, route.Route, X, Y, x, t_2i_min_1, exceptions); while (result != null) // do backtacking over x: TODO: improve this and immidiately find the correct tour. { int t_2i = result.Value; exceptions.Add(t_2i); // step 6. t_2i = result.Value; Edge x_edge = new Edge() { From = t_2i_min_1, To = t_2i, Weight = problem.Weight(t_2i_min_1, t_2i) }; x.Add(x_edge); X.Add(x_edge); // Test the route T' for feasability and weight. y.Add(new Edge() { From = t_2i, To = t_1, Weight = problem.Weight(t_2i, t_2i) }); new_route.Route = this.Replace(route.Route, x, y); y.RemoveLast(); // remove the perliminary y. if (new_route.Route.IsValid()) { // stop the search for now if the route is already better. new_route.RouteWeight = LinKernighanSolver.Weight(problem, new_route.Route); if (new_route.RouteWeight < route.RouteWeight) { // break. OsmSharp.Logging.Log.TraceEvent("LinKernighanSolver", Logging.TraceEventType.Information, "Route {0}:{1}", new_route.Route.ToString(), new_route.RouteWeight); return new_route; } // choose next y. result = this.SelectY(problem, route.Route, X, Y, x, y, null); if (result != null) { int t_2_plus_1 = result.Value; Edge y_edge = new Edge() { From = t_2i, To = t_2_plus_1, Weight = problem.Weight(t_2i, t_2_plus_1) }; y.Add(y_edge); Y.Add(y_edge); // choose next. new_route = this.AfterSelectt5(problem, route, X, Y, x, y); if (new_route.RouteWeight < route.RouteWeight) { // break. OsmSharp.Logging.Log.TraceEvent("LinKernighanSolver", Logging.TraceEventType.Information, "Route {0}:{1}", new_route.Route.ToString(), new_route.RouteWeight); return new_route; } // remove y again. y.RemoveLast(); } x.RemoveLast(); break; // the other x cannot be valid! } // backtrack over x. x.RemoveLast(); result = this.SelectX(problem, route.Route, X, Y, x, t_2i_min_1, exceptions); } return new_route; }
private RouteFound AfterSelectt4(IProblem problem, RouteFound route, EdgeSet X, EdgeSet Y, EdgeList x, EdgeList y) { int t_1 = x[0].From; int t_3 = y[0].To; int t_4 = x[1].To; // try and find a better route with t_1. RouteFound new_route = new RouteFound() { RouteWeight = float.MaxValue, Route = null }; // choose t_5 for backtracking later. HashSet<int> t_5_exceptions = new HashSet<int>(); int? result = this.SelectY(problem, route.Route, X, Y, x, y, t_5_exceptions); while (result != null) { // choose t_5. int t_5 = result.Value; t_5_exceptions.Add(t_5); Edge y_2 = new Edge() { From = t_4, To = t_5, Weight = problem.Weight(t_4, t_5) }; y.Add(y_2); Y.Add(y_2); // try and find a better route by selecting more customer. new_route = this.AfterSelectt5(problem, route, X, Y, x, y); if (new_route.Route != null && new_route.RouteWeight < route.RouteWeight) { // trackback to t_1 if a better route is found. break; } // remove and backtrack y_2. y.RemoveLast(); result = this.SelectY(problem, route.Route, X, Y, x, y, t_5_exceptions); } // choose t_5 return new_route; }
private RouteFound AfterSelectt3(IProblem problem, RouteFound route, EdgeSet X, EdgeSet Y, EdgeList x, EdgeList y) { int t_1 = x[0].From; int t_3 = y[0].To; // try and find a better route with t_1. RouteFound new_route = new RouteFound() { RouteWeight = float.MaxValue, Route = null }; // choose t_4 for backtracking later. HashSet<int> t_4_exceptions = new HashSet<int>(); int? result = this.SelectX(problem, route.Route, X, Y, x, t_3, t_4_exceptions); while (result != null) { // select t_4. int t_4 = result.Value; t_4_exceptions.Add(t_4); // add to x and test with perliminary y. Edge x_edge = new Edge() { From = t_3, To = t_4, Weight = problem.Weight(t_3, t_4) }; x.Add(x_edge); X.Add(x_edge); // Test the route T' for feasability and weight. y.Add(new Edge() { From = t_4, To = t_1, Weight = problem.Weight(t_4, t_1) }); new_route.Route = this.Replace(route.Route, x, y); y.RemoveLast(); // remove the perliminary y. if (new_route.Route.IsValid()) { // stop the search for now if the route is already better. new_route.RouteWeight = LinKernighanSolver.Weight(problem, new_route.Route); if (new_route.RouteWeight < route.RouteWeight) { // break. OsmSharp.Logging.Log.TraceEvent("LinKernighanSolver", Logging.TraceEventType.Information, "Route {0}:{1}", new_route.Route.ToString(), new_route.RouteWeight); x.RemoveLast(); // remove the latest x here! break; } } // choose t_5 here. new_route = this.AfterSelectt4(problem, route, X, Y, x, y); if (new_route.Route != null && new_route.RouteWeight < route.RouteWeight) { // trackback to t_1 if a better route is found. break; } // reset the new route. new_route.Route = null; new_route.RouteWeight = float.MaxValue; // remove and backtrack x_2. x.RemoveLast(); result = this.SelectX(problem, route.Route, X, Y, x, t_3, t_4_exceptions); } // choose t_4 return new_route; }
private RouteFound AfterSelectt2(IProblem problem, RouteFound route, EdgeSet X, EdgeSet Y, EdgeList x) { int t_2 = x[0].To; // try and find a better route with t_1. RouteFound new_route = new RouteFound() { RouteWeight = float.MaxValue, Route = null }; // step 4 and step 10. HashSet<int> t_3_exceptions = new HashSet<int>(); EdgeList y = new EdgeList(); int? result = this.SelectY(problem, route.Route, X, Y, x, y, t_3_exceptions); while (result != null) { // select t_3. int t_3 = result.Value; t_3_exceptions.Add(t_3); // add y_1 to the edge list. Edge y_edge = new Edge() { From = t_2, To = t_3, Weight = problem.Weight(t_2, t_3) }; y.Add(y_edge); Y.Add(y_edge); // search route with t_3. new_route = this.AfterSelectt3(problem, route, X, Y, x, y); if (new_route.Route != null && new_route.RouteWeight < route.RouteWeight) { // trackback to t_1 if a better route is found. break; } // remove y_1 again and backtrack. y.RemoveLast(); result = this.SelectY(problem, route.Route, X, Y, x, y, t_3_exceptions); } return new_route; }
private RouteFound AfterSelectt1(IProblem problem, RouteFound route, EdgeSet X, EdgeSet Y, int t_1) { // try and find a better route with t_1. RouteFound new_route = new RouteFound() { RouteWeight = float.MaxValue, Route = null }; // step 3 and step 11. HashSet<int> t_2_exceptions = new HashSet<int>(); EdgeList x = new EdgeList(); int? result = this.SelectX(problem, route.Route, X, Y, x, t_1, t_2_exceptions); while (result != null) { // select t_2. int t_2 = result.Value; t_2_exceptions.Add(t_2); // add x_1 to the edge list. Edge x_edge = new Edge() { From = t_1, To = t_2, Weight = problem.Weight(t_1, t_2) }; x.Add(x_edge); X.Add(x_edge); // search route with t_2. new_route = this.AfterSelectt2(problem, route, X, Y, x); if (new_route.Route != null && new_route.RouteWeight < route.RouteWeight) { // trackback to t_1 if a better route is found. break; } // remove x_1 again and backtrack. x.RemoveLast(); result = this.SelectX(problem, route.Route, X, Y, x, t_1, t_2_exceptions); } // step 3 and step 11. return new_route; }
///// <summary> ///// A naive selection method. ///// </summary> ///// <param name="problem"></param> ///// <param name="route"></param> ///// <param name="X"></param> ///// <param name="Y"></param> ///// <param name="x"></param> ///// <param name="y"></param> ///// <param name="exceptions"></param> ///// <returns></returns> //private int? SelectY( // IProblem problem, FixedSymmetricRoute route, EdgeSet X, EdgeSet Y, EdgeList x, EdgeList y, HashSet<int> exceptions) //{ // int from = x.Last.To; // // search an edge with weight smaller than g. // // VERY NAIVE METHOD! // List<int> test_list = new List<int>(); // float best_extra = float.MaxValue; // int? best_customer = null; // for (int other_customer = 0; other_customer < problem.Size; other_customer++) // { // if (other_customer != from && exceptions != null && !exceptions.Contains(other_customer)) // { // if (!x.Contains(from, other_customer) // && !route.Contains(from, other_customer)) // //&& !Y.Contains(from, other_customer)) // //&& !X.Contains(from, other_customer)) // { // float extra = problem.Weight(from, other_customer); // if (y.Weight + extra < x.Weight) // { // if (x.Count < 3) // { // best_customer = other_customer; // best_extra = extra; // break; // } // test_list.Add(other_customer); // if (extra < best_extra) // { // best_customer = other_customer; // best_extra = extra; // if (x.Count < 3) // { // break; // } // } // } // } // } // } // return best_customer; //} /// <summary> /// Selects with special priority. /// </summary> /// <param name="problem"></param> /// <param name="route"></param> /// <param name="X"></param> /// <param name="Y"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="exceptions"></param> /// <returns></returns> private int?SelectY( IProblem problem, FixedSymmetricRoute route, EdgeSet X, EdgeSet Y, EdgeList x, EdgeList y, HashSet <int> exceptions) { int from = x.Last.To; // search an edge with weight smaller than g. //float best_priority = float.MinValue; int?best_customer = null; foreach (Edge edge in _sparse_set.GetFor(from)) { if (exceptions == null || !exceptions.Contains(edge.To)) { if (edge.From != edge.To && !x.Contains(edge) && !y.Contains(edge) && !route.Contains(edge.From, edge.To) //&& !Y.Contains(from, other_customer)) && !X.Contains(from, edge.To)) { double extra = edge.Weight; if (y.Weight + extra < x.Weight) { //if (x.Count < 2) //{ best_customer = edge.To; break; //} //// calculate priority. //int? x_other = this.SelectX(problem, route, X, Y, x, edge.To, null); //float priority = float.MinValue; //if (x_other != null) //{ // float x_other_weight = problem.Weight(edge.To, x_other.Value); // priority = x_other_weight - extra; //} //if (priority > best_priority) //{ // best_customer = edge.To; // best_priority = priority; //} } } } } return(best_customer); }
private RouteFound AfterSelectt5(IProblem problem, RouteFound route, EdgeSet X, EdgeSet Y, EdgeList x, EdgeList y) { int t_1 = x[0].From; int t_2i_min_1 = y[y.Count - 1].To; // try and find a better route with t_1. RouteFound new_route = new RouteFound() { RouteWeight = float.MaxValue, Route = null }; HashSet <int> exceptions = new HashSet <int>(); int? result = this.SelectX(problem, route.Route, X, Y, x, t_2i_min_1, exceptions); while (result != null) // do backtacking over x: TODO: improve this and immidiately find the correct tour. { int t_2i = result.Value; exceptions.Add(t_2i); // step 6. t_2i = result.Value; Edge x_edge = new Edge() { From = t_2i_min_1, To = t_2i, Weight = problem.Weight(t_2i_min_1, t_2i) }; x.Add(x_edge); X.Add(x_edge); // Test the route T' for feasability and weight. y.Add(new Edge() { From = t_2i, To = t_1, Weight = problem.Weight(t_2i, t_2i) }); new_route.Route = this.Replace(route.Route, x, y); y.RemoveLast(); // remove the perliminary y. if (new_route.Route.IsValid()) { // stop the search for now if the route is already better. new_route.RouteWeight = LinKernighanSolver.Weight(problem, new_route.Route); if (new_route.RouteWeight < route.RouteWeight) { // break. Console.WriteLine("Route {0}:{1}", new_route.Route.ToString(), new_route.RouteWeight); return(new_route); } // choose next y. result = this.SelectY(problem, route.Route, X, Y, x, y, null); if (result != null) { int t_2_plus_1 = result.Value; Edge y_edge = new Edge() { From = t_2i, To = t_2_plus_1, Weight = problem.Weight(t_2i, t_2_plus_1) }; y.Add(y_edge); Y.Add(y_edge); // choose next. new_route = this.AfterSelectt5(problem, route, X, Y, x, y); if (new_route.RouteWeight < route.RouteWeight) { // break. Console.WriteLine("Route {0}:{1}", new_route.Route.ToString(), new_route.RouteWeight); return(new_route); } // remove y again. y.RemoveLast(); } x.RemoveLast(); break; // the other x cannot be valid! } // backtrack over x. x.RemoveLast(); result = this.SelectX(problem, route.Route, X, Y, x, t_2i_min_1, exceptions); } return(new_route); }
private RouteFound AfterSelectt4(IProblem problem, RouteFound route, EdgeSet X, EdgeSet Y, EdgeList x, EdgeList y) { int t_1 = x[0].From; int t_3 = y[0].To; int t_4 = x[1].To; // try and find a better route with t_1. RouteFound new_route = new RouteFound() { RouteWeight = float.MaxValue, Route = null }; // choose t_5 for backtracking later. HashSet <int> t_5_exceptions = new HashSet <int>(); int? result = this.SelectY(problem, route.Route, X, Y, x, y, t_5_exceptions); while (result != null) { // choose t_5. int t_5 = result.Value; t_5_exceptions.Add(t_5); Edge y_2 = new Edge() { From = t_4, To = t_5, Weight = problem.Weight(t_4, t_5) }; y.Add(y_2); Y.Add(y_2); // try and find a better route by selecting more customer. new_route = this.AfterSelectt5(problem, route, X, Y, x, y); if (new_route.Route != null && new_route.RouteWeight < route.RouteWeight) { // trackback to t_1 if a better route is found. break; } // remove and backtrack y_2. y.RemoveLast(); result = this.SelectY(problem, route.Route, X, Y, x, y, t_5_exceptions); } // choose t_5 return(new_route); }
private RouteFound AfterSelectt3(IProblem problem, RouteFound route, EdgeSet X, EdgeSet Y, EdgeList x, EdgeList y) { int t_1 = x[0].From; int t_3 = y[0].To; // try and find a better route with t_1. RouteFound new_route = new RouteFound() { RouteWeight = float.MaxValue, Route = null }; // choose t_4 for backtracking later. HashSet <int> t_4_exceptions = new HashSet <int>(); int? result = this.SelectX(problem, route.Route, X, Y, x, t_3, t_4_exceptions); while (result != null) { // select t_4. int t_4 = result.Value; t_4_exceptions.Add(t_4); // add to x and test with perliminary y. Edge x_edge = new Edge() { From = t_3, To = t_4, Weight = problem.Weight(t_3, t_4) }; x.Add(x_edge); X.Add(x_edge); // Test the route T' for feasability and weight. y.Add(new Edge() { From = t_4, To = t_1, Weight = problem.Weight(t_4, t_1) }); new_route.Route = this.Replace(route.Route, x, y); y.RemoveLast(); // remove the perliminary y. if (new_route.Route.IsValid()) { // stop the search for now if the route is already better. new_route.RouteWeight = LinKernighanSolver.Weight(problem, new_route.Route); if (new_route.RouteWeight < route.RouteWeight) { // break. Console.WriteLine("Route {0}:{1}", new_route.Route.ToString(), new_route.RouteWeight); x.RemoveLast(); // remove the latest x here! break; } } // choose t_5 here. new_route = this.AfterSelectt4(problem, route, X, Y, x, y); if (new_route.Route != null && new_route.RouteWeight < route.RouteWeight) { // trackback to t_1 if a better route is found. break; } // reset the new route. new_route.Route = null; new_route.RouteWeight = float.MaxValue; // remove and backtrack x_2. x.RemoveLast(); result = this.SelectX(problem, route.Route, X, Y, x, t_3, t_4_exceptions); } // choose t_4 return(new_route); }
private RouteFound AfterSelectt2(IProblem problem, RouteFound route, EdgeSet X, EdgeSet Y, EdgeList x) { int t_2 = x[0].To; // try and find a better route with t_1. RouteFound new_route = new RouteFound() { RouteWeight = float.MaxValue, Route = null }; // step 4 and step 10. HashSet <int> t_3_exceptions = new HashSet <int>(); EdgeList y = new EdgeList(); int? result = this.SelectY(problem, route.Route, X, Y, x, y, t_3_exceptions); while (result != null) { // select t_3. int t_3 = result.Value; t_3_exceptions.Add(t_3); // add y_1 to the edge list. Edge y_edge = new Edge() { From = t_2, To = t_3, Weight = problem.Weight(t_2, t_3) }; y.Add(y_edge); Y.Add(y_edge); // search route with t_3. new_route = this.AfterSelectt3(problem, route, X, Y, x, y); if (new_route.Route != null && new_route.RouteWeight < route.RouteWeight) { // trackback to t_1 if a better route is found. break; } // remove y_1 again and backtrack. y.RemoveLast(); result = this.SelectY(problem, route.Route, X, Y, x, y, t_3_exceptions); } return(new_route); }