Пример #1
0
        /// <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);
        }