/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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; }
/// <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; }
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(); }
/// <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; }
/// <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; }
/// <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; }