internal override MaxTimeSolution Solve(MaxTimeProblem problem) { MaxTimeCalculator calculator = new MaxTimeCalculator( problem); // generate a ATSP solution. IRoute tsp_solution = _tsp_solution; if (tsp_solution == null) { tsp_solution = _tsp_solver.Solve(new TSPProblem(problem)); } // generate subtours from this solution. MaxTimeSolution solution = new MaxTimeSolution(problem.Size, true); // select a random start point. int start = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(problem.Size); // start the first tour. int placed = 0; int previous = -1; // place the first customer. double weight = 0; double total_weight = 0; IRoute route = solution.Add(start); previous = start; while (placed < problem.Size) { // get the next customer from the tsp solution. int next = tsp_solution.GetNeigbours(previous)[0]; // get the weight to the current start. double weight_to_next = problem.WeightMatrix[previous][next]; double weight_to_start = problem.WeightMatrix[next][start]; total_weight = calculator.CalculateOneRouteIncrease( weight, weight_to_next + weight_to_start); weight = calculator.CalculateOneRouteIncrease( weight, weight_to_next); if (total_weight > problem.Max.Value) { // start a new route. route = solution.Add(next); weight = 0; } else { // just insert the next customer. route.InsertAfter(previous, next); //route.InsertAfterAndRemove(previous, next, -1); } // set the previous. previous = next; placed++; } if (!solution.IsValid()) { throw new Exception(); } StringBuilder builder = new StringBuilder(); builder.Append("["); total_weight = 0; for (int idx = 0; idx < solution.Count; idx++) { //IRoute route = routes.Route(idx); route = solution.Route(idx); weight = calculator.CalculateOneRoute(route); builder.Append(" "); builder.Append(weight); builder.Append(" "); total_weight = total_weight + weight; } builder.Append("]"); builder.Append(total_weight); builder.Append(": "); builder.Append(calculator.Calculate(solution)); Console.WriteLine(builder.ToString()); return(solution); }
private void FillRoutes(MaxTimeCalculator calculator, MaxTimeSolution route1, MaxTimeSolution solution, MaxTimeProblem problem) { double[] weights = new double[solution.Count]; // insert all non-placed customers in the order of the first route. HashSet <int> unplaced = new HashSet <int>(); for (int route_idx = 0; route_idx < route1.Count; route_idx++) { IRoute route1_route = route1.Route(route_idx); foreach (int customer in route1_route) { if (!solution.Contains(customer)) { unplaced.Add(customer); } } } for (int idx = 0; idx < solution.Count; idx++) { IRoute route = solution.Route(idx); weights[idx] = calculator.CalculateOneRoute(route); } // insert all non-placed customers in the order of the first route. //for (int route_idx = 0; route_idx < route1.Count; route_idx++) //{ // IRoute route1_route = route1.Route(route_idx); // foreach (int customer in route1_route) // { // if (!solution.Contains(customer)) // { while (unplaced.Count > 0) { int customer = unplaced.First <int>(); // try reinsertion. CheapestInsertionResult result = new CheapestInsertionResult(); result.Increase = double.MaxValue; int target_idx = -1; CheapestInsertionResult unlimited_result = new CheapestInsertionResult(); unlimited_result.Increase = double.MaxValue; int unlimited_target_idx = -1; for (int idx = 0; idx < solution.Count; idx++) { IRoute route = solution.Route(idx); CheapestInsertionResult current_result = CheapestInsertionHelper.CalculateBestPlacement(problem.Weights, route, customer); if (current_result.Increase < result.Increase) { if (weights[idx] + current_result.Increase < problem.Max.Value) { target_idx = idx; result = current_result; if (result.Increase <= 0) { break; } } } if (current_result.Increase < unlimited_result.Increase) { unlimited_target_idx = idx; unlimited_result = current_result; } } if (target_idx < 0) { result = unlimited_result; target_idx = unlimited_target_idx; } // get the target route and insert. IRoute target_route = solution.Route(target_idx); weights[target_idx] = weights[target_idx] + result.Increase; //target_route.InsertAfterAndRemove(result.CustomerBefore, result.Customer, result.CustomerAfter); target_route.InsertAfter(result.CustomerBefore, result.Customer); unplaced.Remove(result.Customer); ////solution.ToString(); //if (!solution.IsValid()) //{ // throw new Exception(); //} } // } //} }
internal override MaxTimeSolution Solve(MaxTimeProblem problem) { MaxTimeCalculator calculator = new MaxTimeCalculator( problem); // generate a ATSP solution. IRoute tsp_solution = _tsp_solution; if (tsp_solution == null) { tsp_solution = _tsp_solver.Solve(new TSPProblem(problem)); } // generate subtours from this solution. MaxTimeSolution solution = new MaxTimeSolution(problem.Size, true); // select a random start point. int start = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(problem.Size); // start the first tour. int placed = 0; int previous = -1; // place the first customer. double weight = 0; double total_weight = 0; IRoute route = solution.Add(start); previous = start; while (placed < problem.Size) { // get the next customer from the tsp solution. int next = tsp_solution.GetNeigbours(previous)[0]; // get the weight to the current start. double weight_to_next = problem.WeightMatrix[previous][next]; double weight_to_start = problem.WeightMatrix[next][start]; total_weight = calculator.CalculateOneRouteIncrease( weight, weight_to_next + weight_to_start); weight = calculator.CalculateOneRouteIncrease( weight, weight_to_next); if (total_weight > problem.Max.Value) { // start a new route. route = solution.Add(next); weight = 0; } else { // just insert the next customer. route.InsertAfter(previous, next); //route.InsertAfterAndRemove(previous, next, -1); } // set the previous. previous = next; placed++; } if (!solution.IsValid()) { throw new Exception(); } StringBuilder builder = new StringBuilder(); builder.Append("["); total_weight = 0; for (int idx = 0; idx < solution.Count; idx++) { //IRoute route = routes.Route(idx); route = solution.Route(idx); weight = calculator.CalculateOneRoute(route); builder.Append(" "); builder.Append(weight); builder.Append(" "); total_weight = total_weight + weight; } builder.Append("]"); builder.Append(total_weight); builder.Append(": "); builder.Append(calculator.Calculate(solution)); OsmSharp.Logging.Log.TraceEvent("TSPPlacementSolver", TraceEventType.Information, builder.ToString()); return solution; }