Búsqueda aleatoria de óptimos con python

Iniciado por Andr0z, Abril 01, 2020, 03:21:57 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Abril 01, 2020, 03:21:57 PM Ultima modificación: Abril 01, 2020, 03:41:55 PM por Andr0z
La búsqueda aleatoria para óptimos es un método directo un tanto burdo. Dicho método evalúa tantas muestras sea posible de manera aleatoria, si la cantidad de muestras es suficiente, eventualmente el óptimo se localizará.

Veamos, para que éste método funcione se tiene que definir la región a evaluar R:[xl,xu]X[yl,yu](donde los subíndices l y u indican los limites inferior y superior respectivamente) , una vez definida dicha región se dispone a evaluar un generador de números aleatorios definido por:

p=pl+(pu-pl)r   Ec. 1

Donde r es un aleatorio entre 0 y 1.

Aplicando la ecuación 1 a nuestra región para y y x quedarían de la siguiente manera:

x=xl+(xu-xl)r   Ec. 2
y=yl+(yu-yl)r   Ec. 3

Teniendo nuestros generadores de números aleatorios tanto para y y x, veamos un ejemplo práctico de su aplicación:

Tenemos que encontrar el mínimo de nuestra función z=cosx*cosy*x*exp(x-(y2/exp(x2))) en nuestra región cuadrada dada por R(x,y):[-1.5,1.5]X[-1.5,1.5]. La superficie de nuestra región para z será:

     VISTA X,Z


     VISTA Y,Z

Ahora definiendo nuestros generadores y y x, con la región dada R, mediante las ecuaciones 2 y 3 nos quedaría:

x=-1.5+3r   Ec. 4
y=-1.5+3r   Ec. 5

Escribiendo el código en python 3.6.8 para iterar nuestras funciones y evaluar Z, quedaría de la siguiente forma:

Código: python

#definimos la función
def f(x,y):
    z=np.cos(x)*np.cos(y)*x*np.exp(x-np.power(y,2)/np.exp(np.power(x,2)))
    return(z)
#Xmax=0
#Xmax=0

#inicializamos nuestras variables
Xmin=0
Ymin=0
actf=0.1
iteraciones=5000

#Aplicamos el metodo iterativo con nuestras funciones generador
for n in range(iteraciones):
    x=-1.5+3*np.random.rand() #Ec.4
    y=-1.5+3*np.random.rand() #Ec.5
    if f(x,y)<actf:  #f(x,y)>actf sentencia para maximos
        actf=f(x,y)
        Xmin=x
        Ymin=y
        print(str(actf))
       
print("El valor mínimo encontrado para "+str(iteraciones)+" iteraciones es f(x,y) es: "+str(actf))
print("para los valores 'x': " +str(Xmin)+ " y el valor 'y': " +str(Ymin))

# superficie -------------------------------------------------------------   
x=np.linspace(-1.5,1.5,35)
y=np.linspace(-1.5,1.5,35)
xmesh,ymesh=np.meshgrid(x,y)
zmesh=np.cos(xmesh)*np.cos(ymesh)*xmesh*np.exp(xmesh-np.power(ymesh,2)/np.exp(np.power(xmesh,2)))
fig=plt.figure()
ax=fig.add_subplot(1,1,1,projection='3d')
ax.plot_surface(xmesh,ymesh,zmesh,cstride=1,rstride=1)
plt.show()


Ejecutando nuestro código para 5000 iteraciones obtenemos:


Como vemos, el código nos genera una aproximación aceptable al mínimo de la región, comparado con gráfica de la vista XZ y YZ, si quisieramos encontrar el pico máximo de la región solo habría que cambiar la sentencia f(x,y)<actf a f(x,y)>actf en el if del  código en python.