/// <summary> /// Solves the given problem. /// </summary> /// <returns></returns> public sealed override Tour Solve(STSProblem problem, STSPObjective objective, out STSPFitness fitness) { // generate random pool to select customers from. if (_randomPool == null || _randomPool.Size < problem.Weights.Length) { _randomPool = new RandomPool(problem.Weights.Length); } else { _randomPool.Reset(); } // keep adding customers until no more space is left or no more customers available. var tour = problem.CreateEmptyTour(); fitness = new STSPFitness() { Weight = 0, Customers = 1 }; while (_randomPool.MoveNext()) { var customer = _randomPool.Current; if (customer == problem.First || customer == problem.Last) { continue; } Pair location; var cost = CheapestInsertionHelper.CalculateCheapest(tour, problem.Weights, customer, out location); if (cost + fitness.Weight < problem.Max) { tour.InsertAfter(location.From, customer); fitness.Weight = fitness.Weight + cost; fitness.Customers = fitness.Customers + 1; } } // calculate fitness. fitness = objective.Calculate(problem, tour); return(tour); }
/// <summary> /// Applies this operator. /// </summary> public bool Apply(STSProblem problem, STSPObjective objective, Tour solution, out STSPFitness delta) { var before = objective.Calculate(problem, solution); var weights = problem.Weights; delta = objective.Zero; var i = _n; var toInsert = new List <int>(); if (!_insertNew) { // select existing customers, to reinsert. while (solution.Count > 1 && i > 0) { i--; var index = RandomGeneratorExtensions.GetRandom().Generate(solution.Count); var current = solution.GetCustomerAt(index); if (current != Constants.NOT_SET) { if (current != solution.First && current != solution.Last && solution.Remove(current)) { toInsert.Add(current); } } } } else if (solution.Count < problem.Weights.Length) { // select random new customer to insert. while (solution.Count > 1 && i > 0) { i--; var current = RandomGeneratorExtensions.GetRandom().Generate(problem.Weights.Length); if (!solution.Contains(current)) { if (current != solution.First && current != solution.Last && solution.Remove(current)) { toInsert.Add(current); } } } } var fitness = objective.Calculate(problem, solution); foreach (var current in toInsert) { // insert new. Pair position; var cost = CheapestInsertionHelper.CalculateCheapest(solution, weights, current, out position); if (cost + fitness.Weight < problem.Max) { solution.InsertAfter(position.From, current); fitness.Weight = fitness.Weight + cost; fitness.Customers = fitness.Customers + 1; } } var after = objective.Calculate(problem, solution); delta = objective.Subtract(problem, after, before); return(objective.CompareTo(problem, before, after) > 0); }