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); }
/// <summary> /// Does the actual solving. /// </summary> /// <param name="problem"></param> /// <returns></returns> protected override IRoute DoSolve(IProblem problem) { // convert to a symetric problem if needed. IProblem _problem = problem; if (!_problem.Symmetric) { _problem = Convertor.ConvertToSymmetric(_problem); _was_asym = true; } // create the list of customers. _customers = new List <int>(); for (int customer = 0; customer < _problem.Size; customer++) { _customers.Add(customer); } _sparse_set = SparseSetHelper.CreateNearestNeighourSet(_problem, _customers, _customers.Count / 10); //_sparse_set = SparseSetHelper.CreateNonSparseSet(_problem, _customers); // construct a route from the customers. //FixedSymmetricRoute init_route = new FixedSymmetricRoute(_customers); // construct a random route using best-placement. ArbitraryInsertionSolver bp_solver = new ArbitraryInsertionSolver(); IRoute bp_route = bp_solver.Solve(_problem); FixedSymmetricRoute init_route = new FixedSymmetricRoute(bp_route); double init_route_weight = LinKernighanSolver.Weight(_problem, init_route); RouteFound route = new RouteFound() { Route = init_route, RouteWeight = init_route_weight }; Console.WriteLine("Route {0}:{1}", route.Route.ToString(), route.RouteWeight); // step 2. EdgeSet X = new EdgeSet(); EdgeSet Y = new EdgeSet(); IList <int> untried_t_1 = new List <int>(route.Route); while (untried_t_1.Count > 0) { // select t1. int t_1 = untried_t_1[0]; untried_t_1.RemoveAt(0); // search route with t_1. RouteFound t_1_route = this.AfterSelectt1(_problem, route, X, Y, t_1); // select the better route. if (t_1_route.RouteWeight < route.RouteWeight) { untried_t_1 = new List <int>(route.Route); route = RouteFound.SelectBest(route, t_1_route); X = new EdgeSet(); Y = new EdgeSet(); } } // step 2 and step 12. // convert back to asym solution if needed. //result.RemoveAt(result.Count - 1); if (_was_asym) { return(this.ConvertToASymRoute(new List <int>(route.Route))); } return(route.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); }