/// <summary> /// Returns an enumerator. /// </summary> /// <returns></returns> public IEnumerator <Edge> GetEnumerator() { if (_route.IsRound) { return(new EdgeEnumerator(_route.GetEnumerator(), _route.First)); } return(new EdgeEnumerator(_route.GetEnumerator(), -1)); }
public IEnumerator <int> GetEnumerator() { return(new DepotRouteEnumerator(_route.GetEnumerator())); }
public IEnumerator <int> GetEnumerator() { return(new BetweenEnumerator(_route.GetEnumerator(), _first, _last)); }
/// <summary> /// Returns the customer that least increases the length of the given route. /// </summary> /// <param name="problem"></param> /// <param name="route"></param> /// <param name="customers"></param> /// <param name="costs"></param> /// <returns></returns> public static CheapestInsertionResult CalculateBestPlacement( IProblemWeights problem, IRoute route, ICollection <int> customers, IInsertionCosts costs) { // initialize the best placement result. CheapestInsertionResult best = new CheapestInsertionResult(); best.Increase = float.MaxValue; // loop over all customers in the route. if (route.Count > 0) { // there have to be at least two customers. IEnumerator <int> route_enumerator = route.GetEnumerator(); if (!route_enumerator.MoveNext()) { // this route is empty throw new ArgumentException("Route needs to be initialized with at least two customers!"); } int customer_before = route_enumerator.Current; int customer_after = -1; while (route_enumerator.MoveNext()) { // keep moving! customer_after = route_enumerator.Current; InsertionCost cost = costs.PopCheapest(customer_before, customer_after); bool found = false; while (!found) { // test if the costs are empty. if (cost == null) { // re-initialize the costs with all customers under consideration. foreach (int customer in customers) { costs.Add(customer_before, customer_after, customer, (float)problem.WeightMatrix[customer_before][customer] + (float)problem.WeightMatrix[customer][customer_after] - (float)problem.WeightMatrix[customer_before][customer_after]); } // pop the cheapest again! cost = costs.PopCheapest(customer_before, customer_after); } else if (customers.Contains(cost.Customer)) { // the customer is found! found = true; } else { // pop the cheapest again! cost = costs.PopCheapest(customer_before, customer_after); } } if (cost.Cost < best.Increase) { // the costs is better than the current cost! best = new CheapestInsertionResult() { Customer = cost.Customer, CustomerAfter = customer_after, CustomerBefore = customer_before, Increase = cost.Cost }; if (best.Increase == 0) { // immidiately return if smaller than epsilon. return(best); } } // set the after to the before. customer_before = route_enumerator.Current; } // if the round is a round try first-last. if (route.IsRound) { // the route is a round! customer_after = route.First; InsertionCost cost = costs.PopCheapest(customer_before, customer_after); bool found = false; while (!found) { // test if the costs are empty. if (cost == null) { // re-initialize the costs with all customers under consideration. foreach (int customer in customers) { costs.Add(customer_before, customer_after, customer, (float)problem.WeightMatrix[customer_before][customer] + (float)problem.WeightMatrix[customer][customer_after] - (float)problem.WeightMatrix[customer_before][customer_after]); } // pop the cheapest again! cost = costs.PopCheapest(customer_before, customer_after); } else if (customers.Contains(cost.Customer)) { // the customer is found! found = true; } else { // pop the cheapest again! cost = costs.PopCheapest(customer_before, customer_after); } } if (cost.Cost < best.Increase) { // the costs is better than the current cost! best = new CheapestInsertionResult() { Customer = cost.Customer, CustomerAfter = customer_after, CustomerBefore = customer_before, Increase = cost.Cost }; if (best.Increase == 0) { // immidiately return if smaller than epsilon. return(best); } } } } else { // route needs to be initialized. throw new ArgumentException("Route needs to be initialized with at least two customers!"); } // return result. return(best); }
/// <summary> /// Returns the customer that least increases the length of the given route. /// </summary> /// <param name="problem"></param> /// <param name="route"></param> /// <param name="customers"></param> /// <param name="costs"></param> /// <returns></returns> public static CheapestInsertionResult CalculateBestPlacement( IProblemWeights problem, IRoute route, ICollection<int> customers, IInsertionCosts costs) { // initialize the best placement result. CheapestInsertionResult best = new CheapestInsertionResult(); best.Increase = float.MaxValue; // loop over all customers in the route. if (route.Count > 0) { // there have to be at least two customers. IEnumerator<int> route_enumerator = route.GetEnumerator(); if (!route_enumerator.MoveNext()) { // this route is empty throw new ArgumentException("Route needs to be initialized with at least two customers!"); } int customer_before = route_enumerator.Current; int customer_after = -1; while (route_enumerator.MoveNext()) { // keep moving! customer_after = route_enumerator.Current; InsertionCost cost = costs.PopCheapest(customer_before, customer_after); bool found = false; while(!found) { // test if the costs are empty. if (cost == null) { // re-initialize the costs with all customers under consideration. foreach (int customer in customers) { costs.Add(customer_before, customer_after, customer, (float)problem.WeightMatrix[customer_before][customer] + (float)problem.WeightMatrix[customer][customer_after] - (float)problem.WeightMatrix[customer_before][customer_after]); } // pop the cheapest again! cost = costs.PopCheapest(customer_before, customer_after); } else if (customers.Contains(cost.Customer)) { // the customer is found! found = true; } else { // pop the cheapest again! cost = costs.PopCheapest(customer_before, customer_after); } } if (cost.Cost < best.Increase) { // the costs is better than the current cost! best = new CheapestInsertionResult() { Customer = cost.Customer, CustomerAfter = customer_after, CustomerBefore = customer_before, Increase = cost.Cost }; if (best.Increase == 0) { // immidiately return if smaller than epsilon. return best; } } // set the after to the before. customer_before = route_enumerator.Current; } // if the round is a round try first-last. if (route.IsRound) { // the route is a round! customer_after = route.First; InsertionCost cost = costs.PopCheapest(customer_before, customer_after); bool found = false; while (!found) { // test if the costs are empty. if (cost == null) { // re-initialize the costs with all customers under consideration. foreach (int customer in customers) { costs.Add(customer_before, customer_after, customer, (float)problem.WeightMatrix[customer_before][customer] + (float)problem.WeightMatrix[customer][customer_after] - (float)problem.WeightMatrix[customer_before][customer_after]); } // pop the cheapest again! cost = costs.PopCheapest(customer_before, customer_after); } else if (customers.Contains(cost.Customer)) { // the customer is found! found = true; } else { // pop the cheapest again! cost = costs.PopCheapest(customer_before, customer_after); } } if (cost.Cost < best.Increase) { // the costs is better than the current cost! best = new CheapestInsertionResult() { Customer = cost.Customer, CustomerAfter = customer_after, CustomerBefore = customer_before, Increase = cost.Cost }; if (best.Increase == 0) { // immidiately return if smaller than epsilon. return best; } } } } else { // route needs to be initialized. throw new ArgumentException("Route needs to be initialized with at least two customers!"); } // return result. return best; }