예제 #1
0
 /// <summary>
 /// Perform an operation on the current solution.
 /// </summary>
 /// <param name="operation">The local search operation to be performed.</param>
 /// <returns>If the operation improved the best known upper bound on the cost.</returns>
 public virtual bool PerformOperation(LocalSearchOperation operation)
 {
     this.PerformedOperations.Add(operation);
     operation.Execute();
     if (this.CurrentSolution.Cost < this.BestCost)
     {
         this.BestCost  = this.CurrentSolution.Cost;
         this.BestWidth = this.CurrentSolution.Width;
         return(true);
     }
     return(false);
 }
        /// <summary>
        /// Perform a single iteration of the local search.
        /// </summary>
        /// <returns>Should the search continue?</returns>
        protected virtual bool PerformIteration()
        {
            LocalSearchOperation candidate = this.GetCandidate();

            if (candidate == null)
            {
                return(false);
            }

            this.focus.PerformOperation(candidate);
            this.UpdateFocus();
            Console.WriteLine($"{this.focus.CurrentSolution.Width.ToString("N2")} {this.focus.CurrentSolution.Cost.ToString("N0")}");
            return(true);
        }
        protected override LocalSearchOperation GetCandidate()
        {
            LocalSearchOperation candidate = null;
            double cost = this.cost;

            foreach (var op in this.operators)
            {
                foreach (var operation in op.Operations(this.focus.CurrentSolution, this.randomNumberGenerator))
                {
                    this.ExploredSolutions++;
                    if (operation.Cost - cost < -PRECISION)
                    {
                        candidate = operation;
                        cost      = candidate.Cost;
                    }
                }
            }
            return(candidate);
        }
        protected override bool PerformIteration()
        {
            if (this.CurrentComputationTime - this.previousCooling > this.Q)
            {
                this.previousCooling = this.CurrentComputationTime;
                this.T *= ALPHA;
            }

            LocalSearchOperation candidate = this.GetCandidate();

            if (candidate.Cost < this.focus.CurrentSolution.Cost)
            {
                if (candidate.Cost < this.focus.BestCost)
                {
                    this.iterationsWithoutImprovement = 0;
                    Console.WriteLine($"{this.CurrentComputationTime.ToString("N0")}: {this.focus.BestWidth.ToString("N2")} {candidate.Cost.ToString("N0")} | T={this.T.ToString("N2")}");
                }
                this.focus.PerformOperation(candidate);
                var focus = this.focus;
                if (focus != this.UpdateFocus())
                {
                    this.Q = this.computeCoolingInterval(this.T, this.targetT, (int)(this.MaximumComputationTime - this.CurrentComputationTime));
                }
                //Console.WriteLine($"{this.CurrentComputationTime.ToString("N0")}: {this.focus.CurrentSolution.Width.ToString("N2")} {this.focus.CurrentSolution.Cost.ToString("N0")} | T={this.T.ToString("N2")}");
            }
            else
            {
                if (++this.iterationsWithoutImprovement > this.FailedIterationsUntilReset)
                {
                    this.focus.Revert();
                    this.iterationsWithoutImprovement = 0;
                    Console.WriteLine($"Reset");
                }
                else if (this.acceptDeterioration(candidate.Cost - this.focus.CurrentSolution.Cost, this.T))
                {
                    //Console.WriteLine($"Accepted deterioration of size {(candidate.Cost - this.focus.CurrentSolution.Cost).ToString("N0")}, rejection {this.iterationsWithoutImprovement}");
                    this.focus.PerformOperation(candidate);
                }
            }

            return(true);
        }
        protected override bool PerformIteration()
        {
            LocalSearchOperation candidate = this.GetCandidate();

            // If no better neighbor is found
            if (candidate == null)
            {
                // Revert to the best solution so far.
                // Note: reverting is not necessary, it might be better to remove it.
                Console.WriteLine($"Perturbation of size {this.CurrentPerturbationSize} after {this.Failures + 1} failures; best = {this.focus.BestCost.ToString("F2")}");
                if (this.focus.CurrentSolution.Cost > this.focus.BestCost)
                {
                    this.focus.Revert();
                }

                // Perturb the solution by taking a number of random steps.
                for (int i = 0; i < this.CurrentPerturbationSize; i++)
                {
                    LocalSearchOperation operation = this.operators[this.randomNumberGenerator.Next(this.operators.Length)].GetRandomOperation(this.focus.CurrentSolution, this.randomNumberGenerator);
                    this.focus.PerformOperation(operation);
                }

                Console.WriteLine($"Result of perturbation: {this.focus.CurrentSolution.Width.ToString("F2")} {this.focus.CurrentSolution.Cost.ToString("F0")}");
                this.Failures++;
            }
            else
            {
                if (this.focus.PerformOperation(candidate))
                {
                    this.Failures = 0;
                }
                this.UpdateFocus();
                Console.WriteLine($"{this.focus.CurrentSolution.Width.ToString("F2")} {this.focus.CurrentSolution.Cost.ToString("F0")}");
            }

            return(true);
        }