C#, cálculo numérico: método de cálculo y programa fuente del recocido simulado

Recocido simulado (SA)

El recocido simulado (SA) es uno de los métodos metaheurísticos más simples y conocidos para abordar problemas de  caja negra. problemas de optimización global cuya función objetivo no se da explícitamente y solo puede evaluarse mediante alguna costosa simulación por computadora. Se utiliza masivamente en aplicaciones de la vida real. La principal ventaja de SA es su simplicidad. SA se basa en una analogía con el recocido físico de materiales que evita el inconveniente del enfoque Monte-Carlo (que puede quedar atrapado en mínimos locales), gracias a un criterio de aceptación eficiente de Metropolis. Cuando la evaluación de la función objetivo resulta de procesos de simulación complejos que manipulan un espacio de estado de gran dimensión que involucra mucha memoria, los algoritmos basados ​​en población no son aplicables y SA es la respuesta correcta para abordar tales problemas. Este capítulo es una introducción al tema. Presenta los principios de los algoritmos de optimización de búsqueda local, del cual el recocido simulado es una extensión, y el algoritmo Metropolis, un componente básico de SA. El algoritmo SA básico para la optimización se describe junto con dos propiedades teóricas que son fundamentales para SA: el equilibrio estadístico (inspirado en la física estadística elemental) y la convergencia asintótica (basada en la teoría de la cadena de Markov). El capítulo examina los siguientes temas prácticos de interés para el usuario que desea implementar el algoritmo SA para su aplicación particular: aproximación en tiempo finito del SA teórico, enfriamiento en tiempo polinomial, longitud de la cadena de Markov, criterios de parada y simulación basada en evaluaciones Para ilustrar estos conceptos, este capítulo presenta la aplicación directa de SA a dos problemas de optimización combinatoria NP-hard clásicos y clásicos simples: el problema de la mochila y el problema del viajante de comercio. A continuación, la metodología general de SA se despliega en detalle en una aplicación de la vida real: un problema de planificación de trayectorias de aeronaves a gran escala que implica casi 30 000 vuelos a escala continental europea. Esto ejemplifica cómo abordar los problemas complejos de hoy en día usando el esquema simple de SA explotando características particulares del problema, integrando una implementación informática astuta dentro del algoritmo y estableciendo parámetros definidos por el usuario empíricamente, inspirados en la teoría básica de SA presentada en este capítulo. .

Recocido simulado (SA)

El recocido simulado (SA) es uno de los métodos metaheurísticos más simples y mejor conocidos para resolver problemas difíciles de optimización global de caja negra, donde la función objetivo no se proporciona explícitamente y solo puede evaluarse mediante algunas simulaciones informáticas costosas. Se usa mucho en la vida real. La principal ventaja de SA es su simplicidad. SA se basa en una analogía con el recocido físico de materiales, evitando las desventajas de los métodos de Monte Carlo (posibilidad de quedar atrapado en mínimos locales) debido a los criterios de aceptación efectivos de Metropolis. Cuando la evaluación de la función objetivo se produce mediante procedimientos de simulación complejos que tratan con espacios de estado de gran dimensión que involucran grandes cantidades de memoria, los algoritmos basados ​​en población no son aplicables y SA es la respuesta correcta a estos problemas. Este capítulo es una introducción al tema. Se introduce el principio del algoritmo de optimización de búsqueda local, en el que el algoritmo de recocido simulado es su extensión, y el algoritmo Metropolis es el componente básico de SA. Se describe el algoritmo SA básico para la optimización, junto con dos propiedades teóricas fundamentales de SA: el equilibrio estadístico (inspirado en la física estadística elemental) y la convergencia asintótica (basada en la teoría de la cadena de Markov). Este capítulo examina los siguientes problemas prácticos de interés para los usuarios que deseen implementar algoritmos SA para sus aplicaciones específicas: aproximaciones de tiempo finito a SA teórico, enfriamiento de tiempo polinomial, longitudes de cadena de Markov, criterios de parada y evaluación basada en simulación. Para ilustrar estos conceptos, este capítulo aplica SA directamente a dos problemas de optimización combinatoria NP-hard clásicos y clásicos simples: el problema de la mochila y el problema del viajante de comercio. Luego, el enfoque SA general se despliega en detalle en una aplicación práctica: un problema de planificación de trayectorias de aeronaves a gran escala que involucra casi 30,000 vuelos en todo el continente europeo. Esto ejemplifica cómo se pueden explotar esquemas simples de SA para resolver los problemas complejos de la actualidad mediante la explotación de características específicas del problema, la integración de implementaciones informáticas inteligentes en algoritmos y la configuración empírica de los usuarios, inspirados en la teoría fundamental de SA presentada en este capítulo.

Programa fuente C# de recocido simulado

utilizando el sistema;

espacio de nombres Legalsoft.Truffer
{     /// <summary>     /// recocido simulado     /// </summary>     public class Anneal     {         public Ranq1 myran;





        recocido público()
        {             this.myran = new Ranq1(1234);         }

        public void order(doble[] x, doble[] y, int[] iorder)
        {             const double TFACTR = 0.9;

            int i1;
            int i2;
            int nn;
            int[] n = nuevo int[6];
            camino doble = 0.0;
            doble t = 0,5;
            int ncity = x.Length;
            int nover = 100 * ncity;
            int nlimit = 10 * ncity;
            for (int i = 0; i < ncity - 1; i++)
            {                 i1 = iorder[i];                 i2 = iorden[i + 1];                 ruta += alen(x[i1], x[i2], y[i1], y[i2]);             }             i1 = iorder[nciudad - 1];             i2 = iorden[0];             ruta += alen(x[i1], x[i2], y[i1], y[i2]);






            //Consola.Escribir(@fixed);
            for (int j = 0; j < 100; j++)
            {                 int nsucc = 0;                 for (int k = 0; k < nover; k++)                 {                     do                     {                         n[0] = (int)(ncity * myran.doub());                         n[1] = (int)((ncity - 1) * myran.doub());                         si (n[1] >= n[0])                         {                             ++n[1];                         }                         nn = (n[0] - n[1] + nciudad - 1) % nciudad;                     } mientras (nn < 2);













                    if (myran.doub() < 0.5)
                    {                         n[2] = n[1] + (int)(Math.Abs(nn - 1) * myran.doub()) + 1;                         n[2] %= nciudad;                         double de = trncst(x, y, iorder, n);                         booleano = metrop(de, t);                         si (respuesta)                         {                             ++nsucc;                             camino += de;                             trnspt(orden, n);                         }                     }                     else                     {                         double de = revcst(x, y, iorder, n);














                        booleano = metrop(de, t);
                        si (respuesta)
                        {                             ++nsucc;                             camino += de;                             inversa(orden, n);                         }                     }                     if (nsucc >= nlimit)                     {                         break;                     }                 }                 //Consola.Escribir("{0:6}", "\n");                 //Consola.Escribir("{0:6}", "T = ");                 //Consola.Escribir("{0,12:6}", t);                 //Consola.Escribir("{0,12:














                //Consola.Escribir("{0,12:6}", ruta);
                //Consola.Escribir("{0:6}", "\n");
                //Console.Write("{0:6}", "Movimientos exitosos: ");
                //Consola.Escribir("{0:6}", nsucc);
                //Consola.Escribir("{0:6}", "\n");
                t *= TFACTR;
                si (nsucc == 0)
                {                     retorno;                 }         }             }



        public double revcst(double[] x, double[] y, int[] iorder, int[] n)
        {             double[] xx = new double[4];             doble[] yy = nuevo doble[4];             int ncity = x.Length;             n[2] = (n[0] + nciudad - 1) % nciudad;             n[3] = (n[1] + 1) % nciudad;             for (int j = 0; j < 4; j++)             {                 int ii = iorder[n[j]];                 xx[j] = x[ii];                 yy[j] = y[ii];             }             doble de = -alen(xx[0], xx[2], yy[0], yy[2]);             de -= alen(xx[1], xx[3], yy[1], yy[3]);             de += alen(xx[0], xx[3], yy[0], yy[3]);














            de += alen(xx[1], xx[2], yy[1], yy[2]);
            volver de;
        }

        public void reverse(int[] iorder, int[] n)
        {             int ncity = iorder.Length;             int nn = (1 + ((n[1] - n[0] + nciudad) % nciudad)) / 2;             for (int j = 0; j < nn; j++)             {                 int k = (n[0] + j) % ncity;                 int l = (n[1] - j + nciudad) % nciudad;                 int itmp = orden[k];                 iorden[k] = iorden[l];                 orden[l] = itmp;             }         }










        public double trncst(double[] x, double[] y, int[] iorder, int[] n)
        {             double[] xx = new double[6];             doble[] yy = nuevo doble[6];             int ncity = x.Length;             n[3] = (n[2] + 1) % nciudad;             n[4] = (n[0] + nciudad - 1) % nciudad;             n[5] = (n[1] + 1) % nciudad;             for (int j = 0; j < 6; j++)             {                 int ii = iorder[n[j]];                 xx[j] = x[ii];                 yy[j] = y[ii];             }             doble de = -alen(xx[1], xx[5], yy[1], yy[5]);             de -= alen(xx[0], xx[4], yy[0], yy[4]);














            de -= alen(xx[2], xx[3], yy[2], yy[3]);
            de += alen(xx[0], xx[2], yy[0], yy[2]);
            de += alen(xx[1], xx[3], yy[1], yy[3]);
            de += alen(xx[4], xx[5], yy[4], yy[5]);
            volver de;
        }

        public void trnspt(int[] iorder, int[] n)
        {             int ncity = iorder.Length;             int[] jorder = new int[ncity];             int m1 = (n[1] - n[0] + nciudad) % nciudad;             int m2 = (n[4] - n[3] + nciudad) % nciudad;             int m3 = (n[2] - n[5] + nciudad) % nciudad;             int nn = 0;             for (int j = 0; j <= m1; j++)             {                 int jj = (j + n[0]) % ncity;                 orden[nn++] = orden[jj];             }             for (int j = 0; j <= m2; j++)             {                 int jj = (j + n[3]) % ncity;                 orden[nn++] = orden[jj];















            }
            for (int j = 0; j <= m3; j++)
            {                 int jj = (j + n[5]) % ncity;                 orden[nn++] = orden[jj];             }             for (int j = 0; j < ncity; j++)             {                 iorder[j] = jorder[j];             }         }







        public bool metrop(doble de, doble t)
        {             return de < 0.0 || myran.doub() < Math.Exp(-de / t);         }

        public double alen(doble a, doble b, doble c, doble d)
        {             return Math.Sqrt((b - a) * (b - a) + (d - c) * (d - c));         } }     }




 

Supongo que te gusta

Origin blog.csdn.net/beijinghorn/article/details/132128391
Recomendado
Clasificación