Inscription / Connexion Nouveau Sujet
Niveau Master Maths
Partager :

recherche linéaire (Python)

Posté par Profil hsrn 14-02-20 à 07:12

Bonjour, on nous demande :

On introduit ici la règles de recherche linéaire inexacte, la règle d'Armijo (1966).
La règle d'Armijo consiste étant donné un point courant xk et une direction  de descente dk à
l'itération k∈N∗ à trouver un pas hk+1>0 satisfaisant f(xk+hk+1dk)≤f (xk)+c*hk+1 〈∇f (xk),dk 〉, où  c ∈]0,1/2[ est un paramètre fixé par l'utilisateur.

Proposer une méthode permettant de trouver un tel pas hk+1 et l'implémenter. Pour cela, on pourra considérer une suite décroissante tendant vers 0 et initialisée à la valeur−〈∇f (xk),dkk),dk〉/(L||dk||2), où L est un paramètre fixé par l'utilisateur.

j'ai éssayer de le faire,mais au lieu que ca converge vers le minimum ca m'explose vers +00 (je l'ai testé sur la fonction de Rosenbrock),voici le code que j'ai écrit:


import numpy as np

#definir fonction Rsenbrock
def f(X):
    return (X[0]-1)**2+100*(X[0]**2-X[1])**2  


#Gradient de la fonction
def gradient_f(X):
    return [2*X[0]-2+40*X[0]**3-40*X[0]*X[1],-20*X[0]**2+20*X[1]] #forme developper du gradient*1/10

def norm(X):
    y=np.array(X)
    return (y.dot(y))**0.5

def Armijo(X,L,d,c,f,gradf):
    q=lambda t:f(list(np.array(X)+t*np.array(d)))  
    #initialisation de t
    p=lambda t:np.array(d).dot(gradf(list(np.array(X)+t*np.array(d)))) #derive de q(t)=f(X+td)
    t=-p(0)/(L*(norm(d)**2))
    if c>=0.5 or c<=0:
        print('c doit appartenir a ]0,0.5[')
    else:
        kmax=10
        k=0
        while q(t) > q(0) + c*t*p(0) and k<kmax:
            t=t/2
            k=k+1
    return t

def PasArmigo(x):
    k=0
    iter_max=100
    epsilon=0.0001
    [a,b]=x

    while norm(gradient_f([a,b]))>epsilon and k<iter_max:
        [x[0],x[1]]=[a,b]
        t=Armijo([a,b],100,gradient_f([a,b]),0.4,f,gradient_f)
        a=x[0]-t*(gradient_f(x)[0])
        b=x[1]-t*(gradient_f(x)[1])
        k=k+1
    return(k,x,norm(gradient_f(x)))
print(PasArmigo([-1,1]))


Merci d'avance

Posté par
XZ19
re : recherche linéaire (Python) 14-02-20 à 20:39

Bonjour
J'ai regardé ton programme.  D'abord il faut dire que je n'ai pas tout à fait compris le principe de la recherche du pas,  en particulier le choix de L  est basée sur quelle idée?
Pourquoi L=100?  Je ne connais pas cette méthode  donc pour pouvoir en dire plus ça serait pas mal que tu expliques le pourquoi du comment.

Ceci étant dit je remarque qu'avec ton exemple  x_0=[-1,1]  la première valeur donnée par t est négative, donc tu ne vas pas dans la direction de la descente. Ce qui explique la divergence vers l'infini.

Il  y a donc une erreur de signe. Mais si je corrige l'erreur,   malgré tout, ton algorithme converge mais pas vers  la solution. C'est à dire il y a un problème dans l'application de la méthode.

Posté par
XZ19
re : recherche linéaire (Python) 14-02-20 à 20:43

En fait l'algorithme  s'arrête parce que le max  d'itération est atteint.  Même en l'augmentant ce max autorisé, on n'atteint pas la solution.
A mon avis il y a  convergence mais elle est trop lente. Alors il faut améliorer l'application de la méthode.

Posté par Profil hsrnre : recherche linéaire (Python) 14-02-20 à 22:42

BonsoirXZ19,

Citation :
Il  y a donc une erreur de signe.

Oui vous avez raison, j'ai remarqué ceci en essayant d'écrire le code autrement.
Merci!

Posté par
XZ19
re : recherche linéaire (Python) 14-02-20 à 23:30

Il y a vraiment une analyse à faire sur le choix des paramètres et sur  comment se comporte ton algorithme après avoir fait la correction du signe.  
En effet, sur ton exemple tu prends la valeur  initiale x_0=(-1,1) et  la direction de descente passe par la solution.  
Alors  si tu poses  w(t)=f(x_0-t \nabla f(x0)),  w'(t)  s'annule  t=1/2  et si la méthode donnait ce paramètre la convergence serait  en une seule étape.  

Mais   w'(t)  s'annule 2 fois   entre 0 et 1/2. Très proche de t=0, tu as pour w(t)  un minimum  (local) et je suis  presque certain ton algorithme s'arrête à cet endroit.
En effet  la direction de descente ne change pas, le pas à chaque étape doit surement être nul,   mais le gradient n'étant non nul et bien tu boucles jusque k_max sans avancer.

Posté par Profil hsrnre : recherche linéaire (Python) 15-02-20 à 00:18

Merci pour les explications , c'est beaucoup plus claire!!



Vous devez être membre accéder à ce service...

Pas encore inscrit ?

1 compte par personne, multi-compte interdit !

Ou identifiez-vous :


Rester sur la page

Désolé, votre version d'Internet Explorer est plus que périmée ! Merci de le mettre à jour ou de télécharger Firefox ou Google Chrome pour utiliser le site. Votre ordinateur vous remerciera !