/// <summary>
        /// Obtiene el porcentaje de soluciones aceptadas que se generaron
        /// a partir de una solución inicial con una temperatura
        /// </summary>
        /// <param name="solution">solución inicial para recorrer el espacio de soluciones</param>
        /// <param name="T">temperatura inicial permite conocer el porcentaje de soluciones promedio para dicha  temperatura</param>
        /// <returns>porcentaje de soluciones aceptadas para una temperatura inicial</returns>
        private double percentage_accepted(ISolution solution, double T)
        {
            ISolution s = (ISolution)solution.Clone();
            //Cantidad de soluciones aceptadas
            double c = 0;

            //Se generan N vecinos a partir de una solución
            for (int i = 0; i < N_PERCENTAGE_ACCEPTED; i++)
            {
                ISolution s1 = s.getNeighbour(random);
                //Si el vecino es aceptado se incrementa la cantidad
                //de soluciones aceptadas
                if (isAccepted(s1, solution, T))
                {
                    c++;
                }
                //Siempre se intercambia la solución por el vecino para
                //para explorar más en el conjunto de soluciones
                s = s1;
            }

            //Retorna cantidad de soluciones aceptadas sobre el numero
            //de soluciones que se generon en total
            return((double)c / (double)N_PERCENTAGE_ACCEPTED);
        }
示例#2
0
            private void FindSolutionsRecursive(ArrayList result, int level, ISolutionEnumerator enumerator)
            {
                ISolution solution = GetSolution(level);

                Debug.Assert(solution != enumerator.StartingPartialSolution);

                while (enumerator.FillDescendantSolution(solution))
                {
                    //Console.Write(solution.ToString());
                    //Console.ReadLine();

                    if (solution.IsComplete)
                    {
                        //Console.Write(solution.ToString());
                        //Console.ReadLine();
                        result.Add(solution.Clone());
                    }
                    else
                    {
                        ISolutionEnumerator descendantEnumerator = GetSolutionEnumerator(level + 1);
                        solution.FillDescendantSolutionEnumerator(descendantEnumerator);
                        descendantEnumerator.StartingPartialSolution = solution;

                        FindSolutionsRecursive(result, level + 1, descendantEnumerator);
                    }
                }
            }
        public IEnumerable<ISolution> GetNeighbors(ISolution solution)
        {
            for (int i = 1; i < solution.Count; i++)
                for (int j = i + 1; j <= solution.Count; j++)
                {
                    ISolution item = solution.Clone();
                    var t = item.Items[i];
                    item.Items[i] = item.Items[j];
                    item.Items[j] = t;

                    yield return item;
                }
        }
示例#4
0
        /// <summary>
        /// Calcula un lote a partir de una solucion inicial y una temperatura dada
        /// </summary>
        /// <param name="T">Temperatura en la que se encuentra la simulación</param>
        /// <param name="solution">solucion inicial</param>
        /// <param name="random">objeto permite aleatoriedad</param>
        /// <returns></returns>
        public double calculate_batch(double T, ISolution solution, Random random)
        {
            this.temperature = T;

            ISolution s = (ISolution)solution.Clone();

            best = s;
            //Cantidad de soluciones aceptadas
            int    c = 0;
            double r = 0;

            int iterations = 0;

            finished = false;

            while (c < L && iterations < MAX_ITERATIONS)
            {
                ISolution s1 = s.getNeighbour(random);

                if (s1.calculateCostFunction() < best.calculateCostFunction())
                {
                    best = s1;
                }

                double s1_cost_function = s1.calculateCostFunction();
                double s_cost_function  = s.calculateCostFunction();
                if (s1_cost_function <= (s_cost_function + T))
                {
                    s = s1;
                    c = c + 1;
                    r = r + s1_cost_function;

                    //Guarda todas las soluciones generadas por el lote
                    solutions.Add(s1);
                    //Console.WriteLine(s1_cost_function);
                    costs_functions.Add(s1_cost_function);
                }
                iterations = iterations + 1;
            }


            finished     = c == L;
            lastSolution = s;
            return(r / (double)L);
        }
        public ISolution Combine(ISolution solutionFirst, ISolution solutionSecond)
        {
            Random rnd = new Random();
            ISolution result = solutionFirst.Clone();

            int k = rnd.Next(solutionFirst.Count) + 1;

            for (int i = 1; i <= k; i++)
                result.Items[i] = solutionFirst.Items[i];

            for (int i = 1; i <= solutionSecond.Count; i++)
                if (!result.Items.Contains(solutionSecond.Items[i]))
                {
                    result.Items[k] = solutionSecond.Items[i];
                    k++;
                }
            return result;
        }
        public ISolution GetBestNeighbor(ISolution solution)
        {
            ISolution result = null;

            for (int i = 1; i < solution.Count; i++)
                for (int j = i + 1; j <= solution.Count; j++)
                {
                    ISolution item = solution.Clone();
                    var t = item.Items[i];
                    item.Items[i] = item.Items[j];
                    item.Items[j] = t;

                    if (result == null || result.Cost > item.Cost) result = item;
                }

            if (result == null)
                result = solution;
            return result;
        }
        /// <summary>
        /// Obtiene una temperatura que aumenta la probabilidad
        /// de desplazarse más rapida y efectivamente por el
        /// conjunto de soluciones, evitando de igual forma
        /// que sea un enfriamiento demasiado lentp
        /// </summary>
        /// <param name="solution">Solución inicial (aleatoria)</param>
        /// <param name="T">temperatura inicial arbitraria </param>
        /// <param name="P">
        /// Porcentaje de soluciones que se desea sean aceptadas
        /// por la temperatura inicial que se quiere encontrar. Aprox
        /// .85<= p <= .95
        /// </param>
        /// <returns></returns>
        private double initial_temperature(ISolution solution, double T, double P)
        {
            ISolution s = (ISolution)solution.Clone();

            /**
             * Se calcula el porcentaje de soluciones aceptadas
             * a partir de la temperatura arbitraria que se tomo
             */
            double p = percentage_accepted(s, T);
            double T1, T2;

            /**
             * Si la diferencia entre el porcentaje de soluciones
             * aceptadas a partir de los datos iniciales se acerca
             * bastante al porcentaje de soluciones que se quiere
             * acepte la temperatura inicial es decir p sea casi p
             * se dice que la temperatura dada es un temperatura
             * adecuada para iniciar el algoritmo
             **/
            if (Math.Abs(P - p) <= EP_INITIAL_TEMPERATURE)
            {
                return(T);
            }

            /**
             * Si el porcentaje de soluciones aceptadas (p) es menor
             * al porcentaje P que se desea tener, se incrementa la
             * temperatura al doble
             **/
            if (p < P)
            {
                /**
                 * Mientras el porcentaje de soluciones aceptas p siga
                 * siendo menor que el porcentaje que se desea se aumenta
                 * la temperatura y se evalua hasta que el porcentaje de
                 * aceptados se mayor que el que se desea
                 **/
                while (p < P)
                {
                    T = 2 * T;
                    p = percentage_accepted(s, T);
                }

                /**
                 * --------|------------|-----------
                 *       temp/2        temp
                 **/
                T1 = T / 2;
                T2 = T;
            }
            else
            {
                /**
                 * Por el contrario si el numero de aceptados excede
                 * el porcentaje de aceptados que se desea, la temperatura
                 * se disminuye y se evalua hasta que el porcentaje de aceptados
                 * sea el apropiado
                 **/
                while (p > P)
                {
                    T = T / 2;
                    p = percentage_accepted(s, T);
                }

                /**
                 * --------|------------|-----------
                 *       temp         2 * temp
                 **/
                T1 = T;
                T2 = 2 * T;
            }

            /**
             * Realiza una busqueda binaria entre T1 y T2
             * --------|----------|----------|-----------
             *       T1        ?        T2
             * con el objetivo de encontrar un valor intermedio
             * entre estos que se acerque más al porcentaje de
             * aceptados que se quiere.
             * temp ha sido cambiado entre 2 incrementandolo y
             * decrementandolo por eso se hacen las operaciones
             * respectivas para obtener T1 o T2
             **/
            return(binary_search(s, T1, T2, P));
        }