Ejemplo n.º 1
0
        public static void Subsample <T>(IList <T> items, int count)
        {
            if (items.Count <= count)
            {
                return;
            }

            for (int i = 0; i < count; ++i)
            {
                int swapIndex = Random.Int(i, items.Count);
                T   tmp       = items[i];
                items[i]         = items[swapIndex];
                items[swapIndex] = tmp;
            }
        }
        public T Run(T startSolution, Func <T, double, T> mutationFunction, Func <T, double> objectiveFunction)
        {
            if (startSolution == null)
            {
                throw new ArgumentNullException("startSolution");
            }
            if (mutationFunction == null)
            {
                throw new ArgumentNullException("mutationFunction");
            }
            if (objectiveFunction == null)
            {
                throw new ArgumentNullException("objectiveFunction");
            }

            T      bestSolution = startSolution;
            double minObjective = objectiveFunction(bestSolution);

            int    lastUpdateIteration           = 0;
            int    currentIteration              = 0;
            int    iterationsFromLastReannealing = 0;
            double prevObjective = minObjective;
            T      prevSolution  = bestSolution;

            while (currentIteration < this.MaxIterations && currentIteration - lastUpdateIteration < this.MaxStallingIterations)
            {
                double temperature      = CalcTemperature(iterationsFromLastReannealing);
                T      currentSolution  = mutationFunction(prevSolution, temperature);
                double currentObjective = objectiveFunction(currentSolution);
                double acceptanceProb   = CalcAcceptanceProbability(prevObjective, currentObjective, temperature);

                if (Random.Double() < acceptanceProb)
                {
                    prevObjective = currentObjective;
                    prevSolution  = currentSolution;
                }

                if (currentObjective < minObjective)
                {
                    lastUpdateIteration = currentIteration;
                    minObjective        = currentObjective;
                    bestSolution        = currentSolution;

                    DebugConfiguration.WriteDebugText("Best solution update: {0:0.000}", minObjective);
                }

                ++currentIteration;
                if (currentIteration % this.reportRate == 0)
                {
                    DebugConfiguration.WriteDebugText("Iteration {0}", currentIteration);

                    if (this.AnnealingProgress != null)
                    {
                        this.AnnealingProgress(this, new SimulatedAnnealingProgressEventArgs <T>(currentSolution, bestSolution));
                    }
                }

                if (iterationsFromLastReannealing >= this.ReannealingInterval)
                {
                    iterationsFromLastReannealing = 0;
                    prevSolution = bestSolution;
                    DebugConfiguration.WriteDebugText("Reannealing");
                }
                else
                {
                    ++iterationsFromLastReannealing;
                }
            }

            return(bestSolution);
        }