Beispiel #1
0
        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;
        }