Пример #1
0
        /// <summary>
        /// Implements the actual logic.
        /// </summary>
        /// <param name="problem"></param>
        /// <param name="customers"></param>
        /// <param name="max"></param>
        /// <returns></returns>
        public MaxTimeSolution DoCalculation(MaxTimeProblem problem,
                                             ICollection <int> customers, Second max)
        {
            MaxTimeSolution routes = this.Solve(problem);

            return(routes);
        }
Пример #2
0
        /// <summary>
        /// Calculates the total weight.
        /// </summary>
        /// <param name="solution"></param>
        /// <returns></returns>
        public double Weight(MaxTimeSolution solution)
        {
            double time           = 0;
            double time_above_max = 0;

            for (int idx = 0; idx < solution.Count; idx++)
            {
                // calculate one route.
                double route_time = this.Time(solution.Route(idx));

                // add the total time about max.
                if (route_time > this.Max.Value)
                { // route time too big!
                    time_above_max = time_above_max + (route_time - this.Max.Value);
                }

                // add to the total time.
                time = time + route_time;
            }

            // the route count.
            double route_count = solution.Count;

            // the punished for breaking max.
            double punishment = System.Math.Pow(time_above_max, 4) * route_count;

            return(route_count * time * _cost_per_second + route_count * _cost_per_vehicle + punishment);
        }
Пример #3
0
        /// <summary>
        /// Caculates the DVRP.
        /// </summary>
        /// <param name="weights"></param>
        /// <param name="locations"></param>
        /// <returns></returns>
        public override int[][] CalculateDepot(double[][] weights, GeoCoordinate[] locations)
        {
            // Keeps a local copy of the current calculation points.
            //
            // TODO: find a better solution to make this thread-safe!
            _locations = locations;

            // convert to ints.
            for (int x = 0; x < weights.Length; x++)
            {
                double[] weights_x = weights[x];
                for (int y = 0; y < weights_x.Length; y++)
                {
                    weights_x[y] = weights_x[y];
                }
            }

            // create the problem for the genetic algorithm.
            MatrixProblem  matrix    = MatrixProblem.CreateATSP(weights);
            MaxTimeProblem problem   = new MaxTimeProblem(matrix, this.Max, this.DeliveryTime, 10, 1000);
            List <int>     customers = new List <int>();

            for (int customer = 0; customer < locations.Length; customer++)
            {
                customers.Add(customer);
                problem.CustomerPositions.Add(
                    _locations[customer]);
            }

            MaxTimeSolution routes = this.DoCalculation(problem, customers, this.Max);

            // convert output.
            int[][]  vrp_solution         = new int[routes.Count][];
            double[] vrp_solution_weights = new double[routes.Count];
            for (int idx = 0; idx < routes.Count; idx++)
            {
                OsmSharp.Logging.Log.TraceEvent("OsmSharp.Routing.Optimization.VRP.WithDepot.MaxTime.MaxTimeRouter", TraceEventType.Information,
                                                "Route {0}: {1}s", idx, routes[idx]);

                // get the route.
                IRoute current = routes.Route(idx);

                // calculate the weight.
                vrp_solution_weights[idx] = problem.Time(current);

                // convert the route.
                List <int> route = new List <int>(current);
                if (current.IsRound)
                {
                    route.Add(route[0]);
                }
                vrp_solution[idx] = route.ToArray();
            }

            // construct and return solution.
            return(vrp_solution);
        }
Пример #4
0
        /// <summary>
        /// Calculates the total time.
        /// </summary>
        /// <param name="solution"></param>
        /// <returns></returns>
        public double Time(MaxTimeSolution solution)
        {
            double time = 0;

            for (int idx = 0; idx < solution.Count; idx++)
            {
                time = time + this.Time(solution.Route(idx));
            }
            return(time);
        }
Пример #5
0
        /// <summary>
        /// Calculates the weight difference after merging two routes given the cost to merge them.
        /// </summary>
        /// <param name="solution"></param>
        /// <param name="merge_costs"></param>
        /// <returns></returns>
        public double WeightDifferenceAfterMerge(MaxTimeSolution solution, double merge_costs)
        {
            if (solution.Count < 2)
            { // the solution routes cannot be merged.
                return(double.MaxValue);
            }
            // the route count.
            double route_count = solution.Count - 1;

            return(route_count * merge_costs * _cost_per_second + route_count * _cost_per_vehicle);
        }
Пример #6
0
        /// <summary>
        /// Calculates the tot weight of one solution.
        /// </summary>
        /// <param name="solution"></param>
        /// <returns></returns>
        public double Calculate(MaxTimeSolution solution)
        {
            int vehicles = solution.Count;

//            List<double> above_max = new List<double>();
            double        total                 = 0;
            double        total_above_max       = 0;
            int           total_count_above_max = 0;
            double        max     = -1;
            List <double> weights = new List <double>();

            for (int route_idx = 0; route_idx < solution.Count; route_idx++)
            {
                double weight = this.CalculateOneRoute(solution.Route(
                                                           route_idx));
                weights.Add(weight);
                total = total + weight;
                if (weight > _problem.Max.Value)
                {
                    total_above_max = total_above_max +
                                      (weight - _problem.Max.Value);
                    total_count_above_max++;
                }
                if (max < weight)
                {
                    max = weight;
                }
            }

            //double above_max_factor = 3;
            // multiply with the maximum.
            //fitness.ActualFitness = (vehicles * ((total_above_max) + total));
            //fitness.ActualFitness = (vehicles * ((total_above_max * max) + total));
            //fitness.ActualFitness = (vehicles * ((System.Math.Pow(total_above_max, 1.28)) + total + max));
            return((vehicles * System.Math.Pow(total_above_max, 4)) + total);
            ////fitness.ActualFitness = (vehicles * (total + ((total_count_above_max * above_max_factor) * max)));
            ////fitness.ActualFitness = (total + ((total_count_above_max * above_max_factor) * max));
            //fitness.Vehicles = vehicles;
            //fitness.TotalTime = total;
            //fitness.TotalAboveMax = total_above_max;
            //return fitness;
        }
Пример #7
0
        /// <summary>
        /// Calculates the tot weight of one solution.
        /// </summary>
        /// <param name="solution"></param>
        /// <returns></returns>
        public double Calculate(MaxTimeSolution solution)
        {
            int vehicles = solution.Count;

            //            List<double> above_max = new List<double>();
            double total = 0;
            double total_above_max = 0;
            int total_count_above_max = 0;
            double max = -1;
            List<double> weights = new List<double>();
            for (int route_idx = 0; route_idx < solution.Count; route_idx++)
            {
                double weight = this.CalculateOneRoute(solution.Route(
                    route_idx));
                weights.Add(weight);
                total = total + weight;
                if (weight > _problem.Max.Value)
                {
                    total_above_max = total_above_max +
                        (weight - _problem.Max.Value);
                    total_count_above_max++;
                }
                if (max < weight)
                {
                    max = weight;
                }
            }

            //double above_max_factor = 3;
            // multiply with the maximum.
            //fitness.ActualFitness = (vehicles * ((total_above_max) + total));
            //fitness.ActualFitness = (vehicles * ((total_above_max * max) + total));
            //fitness.ActualFitness = (vehicles * ((System.Math.Pow(total_above_max, 1.28)) + total + max));
            return (vehicles * System.Math.Pow(total_above_max, 4)) + total;
            ////fitness.ActualFitness = (vehicles * (total + ((total_count_above_max * above_max_factor) * max)));
            ////fitness.ActualFitness = (total + ((total_count_above_max * above_max_factor) * max));
            //fitness.Vehicles = vehicles;
            //fitness.TotalTime = total;
            //fitness.TotalAboveMax = total_above_max;
            //return fitness;
        }
Пример #8
0
        public void TestDepotDynamicAsymmetricMultiRouteExchanges()
        {
            // create two routes.
            // 0->11->12->13->14->15->0
            // 0->21->22->23->24->25->0
            var multiRoute = new MaxTimeSolution(0);
            IRoute route1 = multiRoute.Add();
            var customers = new List<int>(route1);
            Assert.AreEqual(1, customers.Count);
            Assert.AreEqual(0, customers[0]);
            route1.InsertAfter(0, 11);
            Assert.AreEqual("0->11", route1.ToString());
            route1.InsertAfter(11, 12);
            route1.InsertAfter(12, 13);
            route1.InsertAfter(13, 14);
            route1.InsertAfter(14, 15);
            IRoute route2 = multiRoute.Add();
            customers = new List<int>(route2);
            Assert.AreEqual(1, customers.Count);
            Assert.AreEqual(0, customers[0]);
            route2.InsertAfter(0, 21);
            Assert.AreEqual("0->21", route2.ToString());
            route2.InsertAfter(21, 22);
            route2.InsertAfter(22, 23);
            route2.InsertAfter(23, 24);
            route2.InsertAfter(24, 25);

            customers = new List<int>(route1);
            Assert.AreEqual(6, customers.Count);
            Assert.AreEqual(0, customers[0]);
            Assert.AreEqual(11, customers[1]);
            Assert.AreEqual(12, customers[2]);
            Assert.AreEqual(13, customers[3]);
            Assert.AreEqual(14, customers[4]);
            Assert.AreEqual(15, customers[5]);

            customers = new List<int>(route2);
            Assert.AreEqual(6, customers.Count);
            Assert.AreEqual(0, customers[0]);
            Assert.AreEqual(21, customers[1]);
            Assert.AreEqual(22, customers[2]);
            Assert.AreEqual(23, customers[3]);
            Assert.AreEqual(24, customers[4]);
            Assert.AreEqual(25, customers[5]);

            // replace the entire first route.
            route1.ReplaceEdgeFrom(0, 0);

            route2.ReplaceEdgeFrom(25, 11);
            route2.ReplaceEdgeFrom(11, 12);
            route2.ReplaceEdgeFrom(12, 13);
            route2.ReplaceEdgeFrom(13, 14);
            route2.ReplaceEdgeFrom(14, 15);

            Assert.IsTrue(multiRoute.IsValid());

            // create two routes.
            // 0->11->12->13->14->15->0
            // 0->21->22->23->24->25->0
            multiRoute = new MaxTimeSolution(0);
            route1 = multiRoute.Add();
            customers = new List<int>(route1);
            Assert.AreEqual(1, customers.Count);
            Assert.AreEqual(0, customers[0]);
            route1.InsertAfter(0, 11);
            Assert.AreEqual("0->11", route1.ToString());
            route1.InsertAfter(11, 12);
            route1.InsertAfter(12, 13);
            route1.InsertAfter(13, 14);
            route1.InsertAfter(14, 15);
            route2 = multiRoute.Add();
            customers = new List<int>(route2);
            Assert.AreEqual(1, customers.Count);
            Assert.AreEqual(0, customers[0]);
            route2.InsertAfter(0, 21);
            Assert.AreEqual("0->21", route2.ToString());
            route2.InsertAfter(21, 22);
            route2.InsertAfter(22, 23);
            route2.InsertAfter(23, 24);
            route2.InsertAfter(24, 25);

            // exchange parts.
            var part1 = new List<int>(route1.Between(11, 13));
            var part2 = new List<int>(route2.Between(23, 25));
            route1.ReplaceEdgeFrom(0, 14);
            route2.ReplaceEdgeFrom(22, 0);

            int previous = 0;
            for (int idx = 0; idx < part2.Count; idx++)
            {
                route1.ReplaceEdgeFrom(previous, part2[idx]);
                previous = part2[idx];
            }
            route1.ReplaceEdgeFrom(previous, 14);

            previous = 22;
            for (int idx = 0; idx < part1.Count; idx++)
            {
                route2.ReplaceEdgeFrom(previous, part1[idx]);
                previous = part1[idx];
            }
            route2.ReplaceEdgeFrom(previous, 0);

            Assert.IsTrue(multiRoute.IsValid());

            customers = new List<int>(route1);
            Assert.AreEqual(6, customers.Count);
            Assert.AreEqual(0, customers[0]);
            Assert.AreEqual(23, customers[1]);
            Assert.AreEqual(24, customers[2]);
            Assert.AreEqual(25, customers[3]);
            Assert.AreEqual(14, customers[4]);
            Assert.AreEqual(15, customers[5]);

            customers = new List<int>(route2);
            Assert.AreEqual(6, customers.Count);
            Assert.AreEqual(0, customers[0]);
            Assert.AreEqual(21, customers[1]);
            Assert.AreEqual(22, customers[2]);
            Assert.AreEqual(11, customers[3]);
            Assert.AreEqual(12, customers[4]);
            Assert.AreEqual(13, customers[5]);

            // create two routes.
            // 0->11->12->13->14->15->0
            // 0->21->22->23->24->25->0
            multiRoute = new MaxTimeSolution(0);
            route1 = multiRoute.Add();
            customers = new List<int>(route1);
            Assert.AreEqual(1, customers.Count);
            Assert.AreEqual(0, customers[0]);
            route1.InsertAfter(0, 11);
            Assert.AreEqual("0->11", route1.ToString());
            route1.InsertAfter(11, 12);
            route1.InsertAfter(12, 13);
            route1.InsertAfter(13, 14);
            route1.InsertAfter(14, 15);
            route2 = multiRoute.Add();
            customers = new List<int>(route2);
            Assert.AreEqual(1, customers.Count);
            Assert.AreEqual(0, customers[0]);
            route2.InsertAfter(0, 21);
            Assert.AreEqual("0->21", route2.ToString());
            route2.InsertAfter(21, 22);
            route2.InsertAfter(22, 23);
            route2.InsertAfter(23, 24);
            route2.InsertAfter(24, 25);

            route1.ReplaceEdgeFrom(12, 15);
            route1.ReplaceEdgeFrom(14, 11);
            route1.ReplaceEdgeFrom(0, 13);

            customers = new List<int>(route1);
            Assert.AreEqual(6, customers.Count);
            Assert.AreEqual(0, customers[0]);
            Assert.AreEqual(13, customers[1]);
            Assert.AreEqual(14, customers[2]);
            Assert.AreEqual(11, customers[3]);
            Assert.AreEqual(12, customers[4]);
            Assert.AreEqual(15, customers[5]);

            route1.ToString();
        }
Пример #9
0
        /// <summary>
        /// Calculates the weight difference after merging two routes given the cost to merge them.
        /// </summary>
        /// <param name="solution"></param>
        /// <param name="merge_costs"></param>
        /// <returns></returns>
        public double WeightDifferenceAfterMerge(MaxTimeSolution solution, double merge_costs)
        {
            if (solution.Count < 2)
            { // the solution routes cannot be merged.
                return double.MaxValue;
            }
            // the route count.
            double route_count = solution.Count - 1;

            return route_count * merge_costs * _cost_per_second + route_count * _cost_per_vehicle;
        }
Пример #10
0
        /// <summary>
        /// Calculates the total weight.
        /// </summary>
        /// <param name="solution"></param>
        /// <returns></returns>
        public double Weight(MaxTimeSolution solution)
        {
            double time = 0;
            double time_above_max = 0;
            for (int idx = 0; idx < solution.Count; idx++)
            {
                // calculate one route.
                double route_time = this.Time(solution.Route(idx));

                // add the total time about max.
                if (route_time > this.Max.Value)
                { // route time too big!
                    time_above_max = time_above_max + (route_time - this.Max.Value);
                }

                // add to the total time.
                time = time + route_time;
            }

            // the route count.
            double route_count = solution.Count;

            // the punished for breaking max.
            double punishment = System.Math.Pow(time_above_max, 4) * route_count;

            return route_count * time * _cost_per_second + route_count * _cost_per_vehicle + punishment;
        }
Пример #11
0
 /// <summary>
 /// Calculates the total time.
 /// </summary>
 /// <param name="solution"></param>
 /// <returns></returns>
 public double Time(MaxTimeSolution solution)
 {
     double time = 0;
     for (int idx = 0; idx < solution.Count; idx++)
     {
         time = time + this.Time(solution.Route(idx));
     }
     return time;
 }