/// <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> /// Calculates the No-depot VRP solution. /// </summary> /// <param name="weights"></param> /// <param name="locations"></param> /// <returns></returns> public override int[][] CalculateNoDepot(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++) { // get the route. IRoute current = routes.Route(idx); // calculate the weight. vrp_solution_weights[idx] = problem.Time(current); OsmSharp.Logging.Log.TraceEvent("OsmSharp.Routing.Optimization.VRP.WithDepot.MaxTime.MaxTimeRouter", TraceEventType.Information, "Route {0}: {1}s", idx, vrp_solution_weights[idx]); // 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; }