public static Solution RandomFeasibleSolution(VrptwProblem problem) { Solution solution = new Solution(problem); var customersToAssign = new List <Customer>(problem.Customers); while (customersToAssign.Count != 0) { Route route = new Route(problem); route.AddCustomer(problem.Depot); while (true) { float totalTime = route.TotalTime(); Customer lastOneInRoute = route.Customers.Last(); var feasibleCustomers = customersToAssign.Where( c => c.ReadyTime >= totalTime + problem.GetDistance(c.Id, lastOneInRoute.Id) || (c.ReadyTime < totalTime + problem.GetDistance(c.Id, lastOneInRoute.Id) && c.DueDate >= totalTime + problem.GetDistance(c.Id, lastOneInRoute.Id))).ToList(); if (feasibleCustomers.Count > 0) { Customer randomCustomer = feasibleCustomers.ElementAt(RandomGenerator.NextInt(feasibleCustomers.Count())); customersToAssign.Remove(randomCustomer); route.AddCustomer(randomCustomer); } else { route.AddCustomer(problem.Depot); solution.Routes.Add(route); break; } } } return(solution); }
/// <summary> /// Creates a new feasible solution chosen randomly from the neighbourbood /// of the <param name="solution">solution</param>. /// </summary> /// <param name="solution">The solution.</param> /// <returns></returns> public static Solution FeasibleNeighbourSolution(Solution solution) { Solution newSolution = (Solution)solution.Clone(); bool isSolutionFeasible; do { int routeToTakeFromIndex, routeToGiveToIndex; RandomGenerator.NextTwoDifferentInts(newSolution.Routes.Count, out routeToTakeFromIndex, out routeToGiveToIndex); Route routeToTakeFrom = newSolution.Routes.ElementAt(routeToTakeFromIndex); Route routeToGiveTo = newSolution.Routes.ElementAt(routeToGiveToIndex); // backup copies in the case the solution was infeasible Route routeToTakeFromCopy = (Route)routeToTakeFrom.Clone(); Route routeToGiveToCopy = (Route)routeToGiveTo.Clone(); // move customer to another route int customerToMoveIndex = RandomGenerator.NextInt(routeToTakeFrom.Customers.Count - 2) + 1; var customerToMove = routeToTakeFrom.Customers.ElementAt(customerToMoveIndex); routeToTakeFrom.RemoveCustomer(customerToMove); int placeToMoveCustomer = RandomGenerator.NextInt(routeToGiveTo.Customers.Count - 2) + 1; routeToGiveTo.AddCustomer(customerToMove, placeToMoveCustomer); isSolutionFeasible = newSolution.IsFeasible(); // if new solution sint feasible, bring back saved routes if (!isSolutionFeasible) { newSolution.Routes[routeToTakeFromIndex] = routeToTakeFromCopy; newSolution.Routes[routeToGiveToIndex] = routeToGiveToCopy; } // if route is empty, remove it from the solution else if (routeToTakeFrom.IsEmpty()) { newSolution.Routes.Remove(routeToTakeFrom); } } while (!isSolutionFeasible); return(newSolution); }