C#, cálculo numérico: método de cálculo y programa fuente C# de minimización Algoritmo simplex (cuesta abajo) basado en recocido simulado

1 recocido simulado

El algoritmo de recocido simulado es en realidad un algoritmo similar a la biónica, que imita el proceso de recocido físico.
Cuando fabricamos acero, si condensamos rápidamente, el estado en este momento es inestable, la disposición de los átomos es desordenada y la energía es muy alta. Y si dejamos que el acero fundido se condense lentamente y se enfríe muy lentamente, entonces el estado en este momento es muy estable y cada molécula tiende a la posición con la energía más baja. El algoritmo de recocido simulado solo usa el principio del proceso de recocido físico para resolver el valor mínimo de un objetivo de optimización (función objetivo).

El algoritmo de recocido simulado se deriva del principio de recocido sólido. Es un algoritmo basado en la probabilidad. El sólido se calienta a una temperatura suficientemente alta y luego se deja enfriar lentamente. Cuando se calienta, las partículas internas del sólido se desordenan con el la temperatura aumenta y la energía interna aumenta.Grande, y las partículas se vuelven gradualmente ordenadas cuando se enfrían lentamente, alcanzando un estado de equilibrio en cada temperatura y finalmente alcanzando el estado fundamental a temperatura ambiente, y la energía interna se reduce al mínimo.
 

2 Algoritmo de recocido simulado

El algoritmo de recocido simulado (Simulated Annealing, SA) fue propuesto por primera vez por Metropolis et al., en 1953. Después de que Kirkpatrick et al usaran por primera vez el algoritmo de recocido simulado para resolver problemas de optimización combinatoria en 1983, se publicó en Science. Todavía se usa ampliamente hasta hoy, este artículo presentará la implementación del código de C# en detalle.
 

3 método simplex

El método simplex es un algoritmo para resolver problemas de programación lineal. El "simplex" en este nombre es un concepto de topología algebraica.
En problemas prácticos, la variable x es multidimensional y hay muchas más restricciones que ejemplos. Esto requiere A una vez: El algoritmo y para todos puede obtener una solución positiva a través de una computadora, y el método símplex es uno de esos algoritmos. El método símplex fue propuesto por primera vez por George Dantzig en 1947. El método símplex es de importancia cruzada para resolver problemas de programación lineal. De hecho, no es solo para programación lineal, sino que también depende en gran medida del símplex en el proceso de resolución de problemas no lineales. problemas de programación Law, el propio George Dantzig también es conocido como el 'padre de la programación lineal', es el prototipo de la película de Hollywood "Mind Catcher".
 

4 programa fuente C#

utilizando el sistema;

espacio de nombres Legalsoft.Truffer
{     /// <summary>     /// Minimización downhill simplex con recocido simulado     /// Minimización downhill simplex con recocido simulado     /// </summary>     public class Amebsa     {         public RealValueFun funk;






        Ranq1 público corrió;
        privado int mps { obtener; colocar; }
        privado int ndim { obtener; colocar; }
        privado doble[] pb { obtener; colocar; }
        privado doble[] y { obtener; colocar; }
        privado doble[,] p { obtener; colocar; }
        privado doble ftol { obtener; }
        privado doble yb { obtener; colocar; }
        privado doble tt { obtener; colocar; }

        public Amebsa(doble[] punto, doble del, RealValueFun funkk, double ftoll)
        {             this.funk = funkk;             this.ran = new Ranq1(1234);             this.ftol = ftol;             this.yb = double.MaxValue;             this.ndim = punto.Longitud;             this.pb = nuevo doble[ndim];             esto.mpts = ndim + 1;             this.y = new double[mpts];             this.p = new double[mpts, ndim];             for (int i = 0; i < mpts; i++)             {                 for (int j = 0; j < ndim; j++)                 {                     p[i, j] = punto[j];                 }















                if (i != 0)
                {                     p[i, i - 1] += del;                 }             }             inidad();         }




        public Amebsa(doble[] punto, doble[] dels, RealValueFun funkk, double ftoll)
        {             this.funk = funkk;             this.ran = new Ranq1(1234);             this.ftol = ftol;             this.yb = double.MaxValue;             this.ndim = punto.Longitud;             this.pb = nuevo doble[ndim];             esto.mpts = ndim + 1;             this.y = new double[mpts];             this.p = new double[mpts, ndim];             for (int i = 0; i < mpts; i++)             {                 for (int j = 0; j < ndim; j++)                 {                     p[i, j] = punto[j];                 }















                if (i != 0)
                {                     p[i, i - 1] += dels[i - 1];                 }             }             inidad();         }




        public Amebsa(doble[,] pp, RealValueFun funkk, double ftoll)
        {             this.funk = funkk;             this.ran = new Ranq1(1234);             this.ftol = ftol;             this.yb = double.MaxValue;             this.ndim = pp.GetLength(1);             this.pb = nuevo doble[ndim];             this.mpts = pp.GetLength(0);             this.y = new double[mpts];             esto.p = pp;








            inidad();
        }

        public void inity()
        {             double[] x = new double[ndim];             for (int i = 0; i < mpts; i++)             {                 for (int j = 0; j < ndim; j++)                 {                     x[j] = p[i, j];                 }                 y[i] = funk.funk(x);             }         }









        public bool anneal(ref int iter, double temperature)
        {             double[] psum = new double[ndim];             tt = -temperatura;             get_psum(p, psum);             for (; ; )             {                 int ilo = 0;                 int ihi = 1;                 doble ylo = y[0] + tt * Math.Log(ran.double());                 doble ynhi = ylo;                 doble yhi = y[1] + tt * Math.Log(ran.double());                 si (ylo > yhi)                 {                     ihi = 0;                     ilo = 1;                     ynhi = yhi;                     yhi = ylo;
















                    ylo = ynhi;
                }
                for (int i = 3; i <= mpts; i++)
                {                     double yt = y[i - 1] + tt * Math.Log(ran.doub());                     si (yt <= ylo)                     {                         ilo = i - 1;                         ylo = yt;                     }                     si (yt > yhi)                     {                         ynhi = yhi;                         ihi = i - 1;                         yhi = yt;                     }                     más si (yt > ynhi)                     {














                        ynhi = yt;
                    }
                }
                double rtol = 2.0 * Math.Abs(yhi - ylo) / (Math.Abs(yhi) + Math.Abs(ylo));
                if (rtol < ftol || iter < 0)
                {                     Globals.SWAP(ref y[0], ref y[ilo]);                     for (int n = 0; n < ndim; n++)                     {                         Globals.SWAP(ref p[0, n], ref p[ilo, n]);                     }                     if (rtol < ftol)                     {                         devuelve verdadero;                     }                     más                     {











                        falso retorno;
                    }
                }
                ruta -= 2;
                double ytry = amotsa(p, y, psum, ihi, ref yhi, -1.0);
                if (ytry <= ylo)
                {                     ytry = amotsa(p, y, psum, ihi, ref yhi, 2.0);                 }                 else if (ytry >= ynhi)                 {                     double ysave = yhi;                     ytry = amotsa(p, y, psum, ihi, ref yhi, 0.5);                     if (ytry >= ysave)                     {                         for (int i = 0; i < mpts; i++)                         {










                            if (i != ilo)
                            {                                 for (int j = 0; j < ndim; j++)                                 {                                     psum[j] = 0.5 * (p[i, j] + p[ilo, j]);                                     p[i, j] = psum[j];                                 }                                 y[i] = funk.funk(psum);                             }                         }                         ruta -= ndim;                         get_psum(p, psum);                     }                 }                 más                 {














                    ++itero;
                }         }
            }

        public void get_psum(double[,] p, double[] psum)
        {             for (int n = 0; n < ndim; n++)             {                 double sum = 0.0;                 for (int m = 0; m < mpts; m++)                 {                     sum += p[m, n];                 }                 psum[n] = suma;             }         }









        public double amotsa(double[,] p, double[] y, double[] psum, int ihi, ref double yhi, double fac) { double[]
        ptry             = new double[ndim];             doble fac1 = (1.0 - fac) / ndim;             doble fac2 = fac1 - fac;             for (int j = 0; j < ndim; j++)             {                 ptry[j] = psum[j] * fac1 - p[ihi, j] * fac2;             }             double yintentar = funk.funk(intentar);             if (ytry <= yb)             {                 for (int j = 0; j < ndim; j++)                 {                     pb[j] = ptry[j];                 }                 yb = yintentar;















            }
            double yflu = ytry -- tt * Math.Log(ran.doub());
            if ( yflu < yhi )
            {                 y [ yhi ] = ytry ;                 yhi = yflu;                 for (int j = 0; j < libre; j++)                 {                     psum[j] += ptry[j] - p[ihi, j];                     p [ dos , j ] = ptry [ j ] ;                 }             }             return yflu ;         } }     }












 

Supongo que te gusta

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