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]))
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.
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.
BonsoirXZ19,
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 et la direction de descente passe par la solution.
Alors si tu poses 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.
Vous devez être membre accéder à ce service...
Pas encore inscrit ?
1 compte par personne, multi-compte interdit !
Ou identifiez-vous :