Пример #1
0
        /// <summary>
        /// Solves the given problem.
        /// </summary>
        /// <returns></returns>
        public override TSolution Solve(TProblem problem, TObjective objective, out TFitness fitness)
        {
            var zero = objective.Zero;

            _log.Log(Logging.TraceEventType.Information, "Started generating initial solution...");

            TFitness globalBestFitness;
            var      globalBest = _generator.Solve(problem, objective, out globalBestFitness);

            _log.Log(Logging.TraceEventType.Information, "Initial solution generated: {0}.", globalBestFitness);

            // report new solution.
            this.ReportIntermidiateResult(globalBest);

            var difference = objective.Zero;

            if (_localSearch.Apply(problem, objective, globalBest, out difference))
            { // localsearch leads to better solution, adjust the fitness.
                globalBestFitness = objective.Subtract(problem, globalBestFitness, difference);

                _log.Log(Logging.TraceEventType.Information, "Improvement found by local search: {0}.", globalBestFitness);

                // report new solution.
                this.ReportIntermidiateResult(globalBest);
            }

            var i     = 0;
            var level = 1;

            while (!this.IsStopped &&
                   (_stopCondition == null || !_stopCondition.Invoke(i, level, problem, objective, globalBest)))
            { // keep running until stop condition is true or this solver is stopped.
                // shake things up a bit, or in other word change neighbourhood.
                var perturbedSolution   = (TSolution)globalBest.Clone();
                var perturbedDifference = objective.Zero;
                _perturber.Apply(problem, objective, perturbedSolution, level, out perturbedDifference);

                // improve things by using a local search procedure.
                var localSearchDifference = objective.Zero;
                _localSearch.ApplyUntil(problem, objective, perturbedSolution, out localSearchDifference);

                // calculate new fitness and compare.
                TFitness newFitness = default(TFitness);
                if (!objective.IsNonContinuous)
                { // solution fitness can be updated by adding the differences.
                    newFitness = objective.Add(problem, globalBestFitness, perturbedDifference);
                    newFitness = objective.Add(problem, newFitness, localSearchDifference);
                }
                else
                { // solution fitness needs to updated every time.
                    newFitness = objective.Calculate(problem, perturbedSolution);
                }

                if (objective.IsBetterThan(problem, newFitness, globalBestFitness))
                { // there was an improvement, keep new solution as global.
                    globalBestFitness = newFitness;
                    globalBest        = perturbedSolution;
                    level             = 1; // reset level.

                    _log.Log(Logging.TraceEventType.Information, "Improvement found by perturber and local search: {0}.", globalBestFitness);

                    // report new solution.
                    this.ReportIntermidiateResult(globalBest);
                }
                else
                {
                    level = level + 1;
                }
            }

            _log.Log(Logging.TraceEventType.Information, "Stop condition reached, best: {0}.", globalBestFitness);

            fitness = globalBestFitness;
            return(globalBest);
        }