C#, Cálculo numérico: método de cálculo y programa fuente de búsqueda de la sección áurea en una dimensión

 

1 El método de búsqueda de la Sección Áurea

Hoy derivamos el método de búsqueda de la sección áurea; consulte también  las notas de clase.

Derivación del método de búsqueda de la sección áurea para encontrar el mínimo de una función f(x) en el intervalo [a,b].

Asumimos

  • f(x) es continua sobre [a,b] y
  • f(x) es "unimodal" sobre [a,b], lo que significa que f(x) tiene sólo un mínimo en [a,b].

Tenga en cuenta que el método también se aplica para encontrar el máximo.

Las condiciones anteriores nos recuerdan el método de bisección y aplicaremos una idea similar: estrechar el intervalo que contiene los valores mínimos de la función de comparación.
Al diseñar el método buscamos satisfacer dos objetivos:

  1. factor de reducción óptimo para el intervalo de búsqueda;
  2. número mínimo de llamadas a funciones.

Con estos objetivos en mente vamos a determinar la ubicación para evaluar la función.

Una opción inspirada en el método de bisección sería calcular el punto medio m = (a+b)/2 y evaluar en x1 y x2, definidos por x1 = m - eps/2 y x2 = m + eps/2, para algunos eps de valor pequeño para el cual f(x1) /= f(x2). Si f(x1) < f(x2), entonces nos queda [a,x1]; de lo contrario, [x2,b] es nuestro nuevo intervalo de búsqueda. Si bien esto reduce a la mitad el intervalo de búsqueda en cada paso, debemos realizar dos nuevas evaluaciones de funciones en cada paso. Esto no es óptimo.

Por lo tanto, solo queremos realizar una nueva evaluación de función en cada paso. Además, queremos un factor de reducción constante, digamos c, para el tamaño del intervalo.

Hoy derivamos el método de búsqueda de la sección áurea; consulte también las notas de clase.

Derive el método de búsqueda de la sección áurea para encontrar el mínimo de la función f(x) en el intervalo [a,b].

Supongamos

f(x) es continua en [a,b], y

f(x) es "unimodal" en [a,b], lo que significa que f(x) tiene sólo un mínimo en [a,b].

Tenga en cuenta que este método también funciona para encontrar el valor máximo.

Las condiciones anteriores nos recuerdan que debemos utilizar el método de bisección, aplicaremos una idea similar: estrechar el intervalo que contiene el valor mínimo de la función de comparación.

Al diseñar nuestro método, buscamos satisfacer dos objetivos:

factor de reducción óptimo para el intervalo de búsqueda;

Número mínimo de llamadas a funciones.

Con estos objetivos en mente, determinaremos dónde evaluar la función.

Una opción inspirada en la bisección es calcular el punto medio m=(a+b)/2 y comparar f(x1 )/=f(x2) para evaluar algunos valores pequeños de eps. Si f(x1) < f(x2), entonces nos queda [a,x1]; de lo contrario, [x2,b] es nuestro nuevo intervalo de búsqueda. Si bien esto reduce a la mitad el intervalo de búsqueda en cada paso, tenemos que realizar dos nuevas evaluaciones de funciones en cada paso. Esto no es óptimo.

Por lo tanto, solo queremos realizar una evaluación de nuevas funciones en cada paso. Además, para el tamaño del intervalo, necesitamos un factor de reducción constante, digamos c.

2 código fuente C#

usando Sistema;

namespace Legalsoft.Truffer
{     /// <summary>     /// Búsqueda de la sección áurea en una dimensión     /// </summary>     public class Golden: Bracketmethod     {         //public choseFunc func { get; colocar; } = nulo;





        público doble xmin {obtener; colocar; }
        público doble fmin { get; colocar; }
        público doble tol { get; colocar; }

        public Golden(doble peaje = 3.0e-8)
        {             this.tol = peaje;         }

        público doble minimizar (función UniVarRealValueFun)
        {             const doble R = 0,61803399;             doble C = 1,0 - R;             doble x1;             doble x2;             doble x0 = hacha;             doble x3 = cx;             if (Math.Abs(cx - bx) > Math.Abs(bx - ax))             {                 x1 = bx;                 x2 = bx + C * (cx - bx);             }             más             {                 x2 = bx;                 x1 = bx - C * (bx - hacha);             }             doble f1 = func.funk(x1);             doble f2 = func.funk(x2);


















            while (Math.Abs(x3 - x0) > tol * (Math.Abs(x1) + Math.Abs(x2)))
            {                 if (f2 < f1)                 {                     shft3(ref x0, ref x1, ref x2, R * x2 + C * x3);                     shft2(ref f1, ref f2, func.funk(x2));                 }                 else                 {                     shft3(ref x3, ref x2, ref x1, R * x1 + C * x0);                     shft2(ref f2, ref f1, func.funk(x1));                 }             }             si (f1 < f2)             {                 xmín = x1;                 fmín = f1;             }
















            más
            {                 xmín = x2;                 fmín = f2;             }             devolver xmin;         } }     }







 

Supongo que te gusta

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