es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Encontrar el óptimo de funciones mediante el método de Newton en R.

Necesitamos encontrar los extremos/óptimos locales de la siguiente función con sus derivadas y el método de Newton en R. Aquí está la tarea y mi algoritmo. Desafortunadamente, no obtengo ningún resultado.

Los algoritmos de localización de raíces también se pueden usar para encontrar los óptimos locales de las funciones. Recordemos que para una función diferenciable f, una condición necesaria para que x∗ sea un óptimo es f′(x∗) = 0. Considera la función

f(x)=x3 −3×2 +1+100sin(x+1)

en el intervalo I = [−6,6]. Usa la función newton_root2 para encontrar las raíces de la derivada f′ en I, luego clasifica todos los puntos estacionarios de f como mínimo local, máximo local o punto de inflexión. ¿En qué punto f alcanza su máximo global en I? Inicia tu algoritmo en diferentes valores iniciales y discute en qué situaciones el algoritmo se queda atascado en óptimos locales (en el sentido de que no encuentra el óptimo global).

f3 <- function(x0) {
  x0^3 - 3*x0^2 + 1 + 100*sin(x0+1)
}

f3_prime <- function(x0) {
  3*x0^2 - 6*x0 + 100*cos(x0+1)
}

f3_primeprime <- function(x0) {
  6*x0 - 6 - 100*-sin(x0+1)
}

algoritmo

eps<- 1e-6
n_max <- 50
x0 <- -6

newton_root2 <- function(f3, f3_prime, f3_primeprime, x0, nmax=50, eps) {
x0 <- -6
n <- 0
while (n <= n_max) {
n <- n + 1
y0 <- f3(x0)
y1 <- f3_prime(x0)
y2 <- f3_primeprime(x0)
if (y1 < eps) {
break(0)
}
x1 <- x0 – (y0/y1) * (1 + (y0 * y2) / (2 * y1)^2)
if (abs((x0 – x1) / x1) < eps) {
print(‘convergente’)
break(0)
}
x0 <- x1
print(paste(label = ‘iteraciones’, n, label = ‘raíz aproximada’, x0))
}
}
“`

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para encontrar los extremos/óptimos locales de la función dada, podemos utilizar el método de Newton para encontrar raíces en la derivada de la función. El algoritmo dado en la tarea intenta implementar este enfoque pero tiene algunos problemas.

    Para mejorar el algoritmo, podemos comenzar corrigiendo algunos errores de sintaxis en el código. En primer lugar, los símbolos de desigualdad utilizados en las funciones f3_prime y f3_prime_prime deben corregirse. En lugar de los signos < y > se deben usar < y > respectivamente. En segundo lugar, el valor inicial de x0 ya está definido como un parámetro de entrada en la función newton_root2 y no debe ser codificado dentro de la función.

    Una vez corregidos estos errores, podemos proceder a utilizar el algoritmo corregido para encontrar los extremos/óptimos locales de la función. Aquí está el algoritmo modificado:

    f3 <- function(x) {
      x^3 - 3*x^2 + 1 + 100*sin(x+1)
    }
    
    f3_prime <- function(x) {
      3*x^2 - 6*x + 100*cos(x+1)
    }
    
    f3_prime_prime <- function(x) {
      6*x - 6 - 100*sin(x+1)
    }
    
    eps <- 1e-6
    n_max <- 50
    
    newton_root2 <- function(f, df, ddf, x0, eps, nmax=50) {
      n <- 1
      while (n <= nmax) {
        y0 <- f(x0)
        y1 <- df(x0)
        y2 <- ddf(x0)
        if (abs(y1) < eps) {
          break
        }
        x1 <- x0 - y1/y2
        if (abs(x1 - x0) < eps) {
          print("converged")
          break
        }
        x0 <- x1
        print(paste("iteration",n,": x =",x0))
        n <- n + 1
      }
      return(x0)
    }
    
    # Encontrar raíces de f'(x) en I = [-6,6]
    roots <- c()
    for (i in c(-6,6)) {
      root <- newton_root2(f3_prime, f3_prime_prime, f3, i, eps, n_max)
      roots <- c(roots, root)
    }
    # Clasificar puntos estacionarios
    points <- c(roots, -1)
    types <- c()
    for (p in points) {
      f_prime <- f3_prime(p)
      f_prime_prime <- f3_prime_prime(p)
      if (f_prime < 0) {
        types <- c(types, "máximo local")
      } else if (f_prime > 0) {
        types <- c(types, "mínimo local")
      } else if (f_prime == 0 & f_prime_prime < 0) {
        types <- c(types, "punto de inflexión (concavo hacia abajo)")
      } else if (f_prime == 0 & f_prime_prime > 0) {
        types <- c(types, "punto de inflexión (concavo hacia arriba)")
      } else {
        types <- c(types, "desconocido")
      }
    }
    print(paste("Puntos estacionarios:", paste(points, collapse=", ")))
    print(paste("Tipos:", paste(types, collapse=", ")))
    
    # Encontrar máximo global de f(x) en I = [-6,6]
    vals <- sapply(seq(-6,6,by=0.01), f3)
    x_max <- seq(-6,6,by=0.01)[which.max(vals)]
    print(paste("Máximo global en x =", x_max))
    

    Este algoritmo primero encuentra las raíces de la derivada f'(x) de la función dada f(x) utilizando el método de Newton con la función newton_root2. Los valores iniciales para encontrar las raíces se establecen como los puntos finales del intervalo [-6,6], ya que sabemos que cualquier punto estacionario de f(x) debe estar dentro de este intervalo.

    Una vez encontradas las raíces, clasificamos cada punto estacionario evaluando los signos de f'(x) y f''(x) en ese punto. Si f'(x) es positivo (respectivamente negativo), el punto es un mínimo (respectivamente máximo) local. Si f'(x) = 0 y f''(x) > 0 (respectivamente f''(x) < 0), el punto es un punto de inflexión con concavidad hacia arriba (respectivamente hacia abajo).

    Finalmente, encontramos el máximo global de f(x) en el intervalo [-6,6] evaluando f(x) en una cuadrícula de puntos en el intervalo y eligiendo el valor máximo.

    Es posible que el método de Newton se quede atrapado en óptimos locales (es decir, no encuentre el óptimo global) dependiendo de la elección de los valores iniciales. En particular, si elegimos valores iniciales que están cerca de un extremo local, es probable que el método converja a ese extremo y no explore puntos más alejados. Para evitar esto, podemos intentar usar diferentes valores iniciales o utilizar un algoritmo de optimización global como el recocido simulado o los algoritmos genéticos.

Comments are closed.