/// <summary> /// Solves the given problem. /// </summary> /// <returns></returns> public sealed override Tour Solve(TSPTWProblem problem, TObjective objective, out float fitness) { // generate random order for unplaced customers. var customers = new List <int>(); for (var customer = 0; customer < problem.Times.Length / 2; customer++) { if (customer != problem.First && customer != problem.Last) { customers.Add(customer); } } customers.Shuffle <int>(); // generate empty route based on problem definition. var route = problem.CreateEmptyTour(); // add all customers by using cheapest insertion. for (var i = 0; i < customers.Count; i++) { CheapestInsertionDirectedHelper.InsertCheapestDirected(route, problem.Times, problem.TurnPenalties, customers[i], float.MaxValue); } // calculate fitness. fitness = objective.Calculate(problem, route); return(route); }
/// <summary> /// Applies this operator. /// </summary> public bool Apply(TSProblem problem, TSPObjective objective, Tour solution, out float delta) { if (problem.Weights.Length <= 2) { delta = 0; return(false); } var before = objective.Calculate(problem, solution); var weights = problem.Weights; var turnPenalties = problem.TurnPenalties; delta = 0; // test switching directions in random order. if (_pool == null || solution.Count != _pool.Size) { // create a new pool. _pool = new RandomPool(solution.Count); } else { // just reset the existing one. _pool.Reset(); } var i = _n; var toInsert = new List <int>(); while (_pool.MoveNext() && i > 0) { i--; var currentId = _pool.Current; var current = solution.GetDirectedId(currentId); if (current != Constants.NOT_SET) { if (current != solution.First && current != solution.Last && solution.Remove(current)) { toInsert.Add(current); } } } foreach (var current in toInsert) { CheapestInsertionDirectedHelper.InsertCheapestDirected(solution, weights, turnPenalties, DirectedHelper.ExtractId(current)); } var after = objective.Calculate(problem, solution); delta = after - before; return(delta < 0); }
/// <summary> /// Solves the given problem. /// </summary> /// <returns></returns> public sealed override Tour Solve(STSProblem problem, STSPObjective objective, out STSPFitness fitness) { // generate empty route based on problem definition. var route = problem.CreateEmptyTour(); fitness = new STSPFitness() { Weight = 0, Customers = 1 }; // generate random pool to select customers from. if (_randomPool == null || _randomPool.Size < problem.Weights.Length) { _randomPool = new RandomPool(problem.Weights.Length / 2); } else { _randomPool.Reset(); } // keep adding customers until no more space is left or no more customers available. while (_randomPool.MoveNext()) { var customer = _randomPool.Current; if (customer == DirectedHelper.ExtractId(route.First) || (route.Last.HasValue && customer == DirectedHelper.ExtractId(route.Last.Value))) { // customer is first or last. continue; } var cost = CheapestInsertionDirectedHelper.InsertCheapestDirected(route, problem.Weights, problem.TurnPenalties, customer, problem.Max - fitness.Weight); if (cost > 0) { fitness.Customers++; fitness.Weight += cost; } } // calculate fitness. fitness = objective.Calculate(problem, route); return(route); }