2013-09-23 5 views
5

Ho una funzione e vorrei trovare i valori massimi e minimi. La mia funzione è questa:Trova i valori minimi e massimi di una funzione

def function(x, y): 
    exp = (math.pow(x, 2) + math.pow(y, 2)) * -1 
    return math.exp(exp) * math.cos(x * y) * math.sin(x * y) 

Ho un intervallo per x [-1, 1] e y [-1, 1]. Mi piacerebbe trovare un modo, limitato a questo intervallo, per scoprire i valori massimo e minimo di questa funzione.

+2

Sei veramente limitato a questa funzione? O vuoi essere in grado di farlo per una funzione arbitraria? Se è solo questa funzione, puoi trovare gli estremi relativi differenziando. – mgilson

+6

Probabilmente dovresti dare un'occhiata qui: http://docs.scipy.org/doc/scipy/reference/optimize.html –

+0

Vuoi preventivi ravvicinati o il massimo virgola mobile esatto? – Shashank

risposta

8

utilizzando, ad esempio, scipy s' fmin (che contiene un'implementazione dell'algoritmo Nelder-Mead), si può provare questo:

import numpy as np 
from scipy.optimize import fmin 
import math 

def f(x): 
    exp = (math.pow(x[0], 2) + math.pow(x[1], 2)) * -1 
    return math.exp(exp) * math.cos(x[0] * x[1]) * math.sin(x[0] * x[1]) 

fmin(f,np.array([0,0])) 

che produce il seguente output:

Optimization terminated successfully. 
    Current function value: -0.161198 
    Iterations: 60 
    Function evaluations: 113 
array([ 0.62665701, -0.62663095]) 

Si prega di tenere presente che:

1) con scipy è necessario convertire la funzione in una funzione accettando un array (ho mostrato come farlo nell'esempio sopra);

2) fmin utilizza, come la maggior parte delle sue coppie, un algoritmo iterativo, pertanto è necessario fornire un punto di partenza (nel mio esempio, ho fornito (0,0)). È possibile fornire diversi punti di partenza per ottenere minimi/massimi diversi.

+0

Fantastico, ma dato che possiamo solo passare un punto di partenza, c'è un modo per limitare la funzione in un intervallo come ho detto nella mia domanda o potrei ricevere un output fuori dal mio intervallo (questo è quello che mi sembra)? Grazie per l'attenzione. – pceccon

+1

Puoi usare un metodo che supporta il bounding delle variabili, come 'fmin_tnc' (è usato in questo modo:' fmin_tnc (f, np.array ([0.5, -0.5]), approx_grad = True, bounds = [(- 1, 1), (- 1,1)]) '). –

1

Ecco qualcosa che fornisce stime abbastanza vicine (non esatte).

import math 
import random 
import sys 

def function(x, y): 
    exp = (math.pow(x, 2) + math.pow(y, 2)) * -1 
    return math.exp(exp) * math.cos(x * y) * math.sin(x * y) 

max_func = - sys.maxint - 1 
min_func = sys.maxint 
maximal_x, maximal_y = None, None 
minimal_x, minimal_y = None, None 

for i in xrange(1000000): 
    randx = random.random()*2 - 1 
    randy = random.random()*2 - 1 
    result = function(randx, randy) 
    max_func = max(max_func, result) 
    if max_func == result: 
     maximal_x, maximal_y = randx, randy 
    min_func = min(min_func, result) 
    if min_func == result: 
     minimal_x, minimal_y = randx, randy 

print "Maximal (x, y):", (maximal_x, maximal_y) 
print "Max func value:", max_func, '\n' 
print "Minimal (x, y):", (minimal_x, minimal_y) 
print "Min func value:", min_func