internal static SparseSet CreateNearestNeighourSet(IProblem problem, IList <int> customers, int n) { // initialize sparse set. SparseSet set = new SparseSet(); // loop over all customers and add their n-nearest neigbours. foreach (int customer in customers) { // initialize nearest list. SortedSet <KeyValuePair <double, int> > nearest_customers = new SortedSet <KeyValuePair <double, int> >( new SortedSetComparer()); // build nearest list. double highest_weight = double.MaxValue; foreach (int neigbour in customers) { if (neigbour != customer) { // do not // calculate weight double weight = problem.Weight(customer, neigbour); // add to nearest list if needed. if (weight < highest_weight) { nearest_customers.Add(new KeyValuePair <double, int>(weight, neigbour)); // remove highest weight. if (nearest_customers.Count > n) { nearest_customers.Remove(nearest_customers.Max); } // set highest weight again. if (nearest_customers.Count == n) { highest_weight = nearest_customers.Max.Key; } } } } // add nearest list to sparseset. foreach (KeyValuePair <double, int> neigbour_pair in nearest_customers) { set.Add(new Edge() { From = customer, To = neigbour_pair.Value, Weight = neigbour_pair.Key }); } } return(set); }
internal static SparseSet CreateNonSparseSet(IProblem problem, IList <int> customers) { // initialize sparse set. SparseSet set = new SparseSet(); // loop over all customers foreach (int customer in customers) { // loop over all customers again. foreach (int neighbour in customers) { if (neighbour != customer) { // do not set.Add(new Edge() { From = customer, To = neighbour, Weight = problem.Weight(customer, neighbour) }); } } } return(set); }
/// <summary> /// Does the actual solving. /// </summary> /// <param name="problem"></param> /// <returns></returns> protected override IRoute DoSolve(IProblem problem) { // convert to a symetric problem if needed. IProblem _problem = problem; if (!_problem.Symmetric) { _problem = Convertor.ConvertToSymmetric(_problem); _was_asym = true; } // create the list of customers. _customers = new List<int>(); for (int customer = 0; customer < _problem.Size; customer++) { _customers.Add(customer); } _sparse_set = SparseSetHelper.CreateNearestNeighourSet(_problem, _customers, _customers.Count / 10); //_sparse_set = SparseSetHelper.CreateNonSparseSet(_problem, _customers); // construct a route from the customers. //FixedSymmetricRoute init_route = new FixedSymmetricRoute(_customers); // construct a random route using best-placement. ArbitraryInsertionSolver bp_solver = new ArbitraryInsertionSolver(); IRoute bp_route = bp_solver.Solve(_problem); FixedSymmetricRoute init_route = new FixedSymmetricRoute(bp_route); double init_route_weight = LinKernighanSolver.Weight(_problem, init_route); RouteFound route = new RouteFound() { Route = init_route, RouteWeight = init_route_weight }; OsmSharp.Logging.Log.TraceEvent("LinKernighanSolver", Logging.TraceEventType.Information, "Route {0}:{1}", route.Route.ToString(), route.RouteWeight); // step 2. EdgeSet X = new EdgeSet(); EdgeSet Y = new EdgeSet(); IList<int> untried_t_1 = new List<int>(route.Route); while (untried_t_1.Count > 0) { // select t1. int t_1 = untried_t_1[0]; untried_t_1.RemoveAt(0); // search route with t_1. RouteFound t_1_route = this.AfterSelectt1(_problem, route, X, Y, t_1); // select the better route. if (t_1_route.RouteWeight < route.RouteWeight) { untried_t_1 = new List<int>(route.Route); route = RouteFound.SelectBest(route, t_1_route); X = new EdgeSet(); Y = new EdgeSet(); } } // step 2 and step 12. // convert back to asym solution if needed. //result.RemoveAt(result.Count - 1); if (_was_asym) { return this.ConvertToASymRoute(new List<int>(route.Route)); } return route.Route; }