Otimização/Método de gradientes conjugados

Fonte: testwiki
Revisão em 16h38min de 16 de abril de 2020 por imported>DannyS712 (<source> -> <syntaxhighlight> (phab:T237267))
(dif) ← Revisão anterior | Revisão atual (dif) | Revisão seguinte → (dif)
Saltar para a navegação Saltar para a pesquisa


Predefinição:Wikipedia

Algumas considerações históricas

  • Este método foi originalmente proposto por Hestenes e Stiefel, em 1952.
  • Seu objetivo inicial foi a resolução de problemas quadráticos sem restrições, mas logo o mesmo foi estendido para casos mais gerais.

O método

Este método pode ser considerado sob dois pontos de vista:

  • Como um método de descida, com busca linear exata;
  • Como um método de resolução de sistema linear, baseado em um processo de ortogonalização.

Predefinição:Definição

Exemplos de conjuntos convexos e côncavos


Predefinição:Definição

Predefinição:Definição

Predefinição:Exercício Predefinição:Resolução


Nota: Uma matriz é definida positiva se, e somente se, todos os seus autovalores são positivos.

Tem-se:

f:n
2f:n(n)2

Sendo f(x)=12xAx+ax+α, segue em particular que f=Ax+a e 2f=A=PΛP, onde Λ é uma matriz diagonal cujos elementos da diagonal são os autovalores de A e P é uma matriz onde as colunas são os autovetores correspondentes aos autovalores.

Note que A é uma matriz simétrica, pois é a matriz Hessiana de uma função com segundas derivadas parciais contínuas, e consequentemente vale 2fxy=2fyx.

Para introduzir o método de direções conjugadas, serão consideradas somente funções quadráticas.

Uma condição necessária de primeira ordem para que x seja um ponto de mínimo para a função f é que f(x)=0. Para o presente caso, a função f é convexa, então, a condição necessária f(x)=0 também é suficiente.

Predefinição:Exercício Predefinição:Resolução

No caso de uma função quadrática, tem-se f(x)=0Ax+a=0, ou seja, x é solução do sistema linear Ax=a.

A resolução de um sistema linear nem sempre pode ser feita numericamente de forma eficiente. Por exemplo, se a matriz do sistema é:

A=[1020111020+1]

A solução do sistema linear corresponde à interseção entre duas retas quase paralelas, e os erros de truncamento podem causar imprecisão na solução obtida computacionalmente.

Analiticamente, o sistema Ax=a tem x=A1a como solução. Então alguém poderia se perguntar: qual o problema em resolver esse sistema linear, se basta calcular a inversa da matriz A e multiplicar pelo vetor a? A resposta é que o calculo da inversa de uma matriz em geral é impraticável computacionalmente, por ter custo muito alto. Por isso, nas situações práticas, onde as matrizes tem ordem bem maior do que 2 (digamos 1000), o cálculo de matrizes inversas não é uma opção.

Assim, com o intuito de desenvolver um método computacional para o cálculo de minimizadores, é preciso utilizar outras técnicas. Considere o seguinte:

Em um método de descida tem-se sempre uma sequencia {xk,tk,dk}, com xk+1=xk+tkdk e tk é um minimizador de f(xk+tdk):t

f(x)=Ax+a

e

0=f(xk+1)=Axk+1+a=A(xk+tkdk)+a=Axk+tkAdk+a

Logo, tkAdk=(Axk+a) e multiplicando por dk obtem-se tkdkAdk=(dkAxk+dka). Consequentemente, o valor de tk é dado por

tk=(dkAxk+adk)dkAdk

Deste modo, o método consistirá de escolher em cada etapa k uma direção dk, e calcular o coeficiente tk pela fórmula anterior, para gerar o próximo ponto xk+1. Mas como escolher a direção dk?

Dado xk e escolhido dk, defina θ:R como θ(t)=f(xk+tdk), ou seja, θ é a restrição da função f à reta que passa pelo ponto xk e que tem direção dk. Logo, derivando a expressão de θ em relação a t, obtem-se

θ(t)=f(xk+tdk)dk

Então, no ponto de mínimo, xk+1, tem-se

0=f(xk+1)dk

Ou seja, a direção dk a ser seguida a partir do ponto xk é ortogonal ao gradiente da função f, no ponto xk+1.

Esquema do método de descida

xk+1=xk+tkdk=(xk1+tk1dk1)+tkdk==x1+t1d1++tkdk=x1+i=1ktidi

Seja x¯ o minimizador da função f. Tem-se

xk+1x¯=x1x¯+i=1ktidi

Mas 0=f(x¯)=Ax¯+a implica que a=Ax¯, logo

f(x)=Ax+a=AxAx¯=A(xx¯)

e consequentemente

A(xk+1x¯)=A(x1x¯)+i=1ktiAdi

Donde f(xk+1)=f(x1)+i=1ktiAdi. Portanto 0=f(xk+1)dk=f(x1)dk+i=1ktidiAdk.

Predefinição:Exercício Predefinição:Resolução

Usando o resultado desse exercício, tem-se ainda que 0=f(xk+1)dk=f(x1)dk+i=1kti(Bdi)(Bdk)

Fazendo δ=Bd, o método do gradiente conjugado escolhe as direções de descida tais que δidj=0,i=j. Mas quando i=j, tem-se na expressão apresentada anteriormente apenas 0=f(x1)dk+tk(Bdk)(Bdk)=f(x1)dk+tkdkAdk

Finalmente, tem-se o algoritmo para este método.

Algoritmo de Hestenes-Stiefel

Uma comparação da convergência do método de descida do gradiente com tamanho de passo ótimo (em verde) e o método do gradiente conjugado (em vermelho) para a minimização da forma quadrática com um sistema linear dado. O gradiente conjugado, assumindo aritmética exata, converge em no máximo n passos onde n é o tamanho da matriz do sistema (no exemplo, n=2).
Primeiro passo: Escolha x0n
  Se f(x0)=0, então pare: x¯=x0
  Senão: d0=f(x0)=Ax0a
  Calcular t0=f(x0)2d0Ad0
  x1=x0+t0d0


Passo iterativo k: Dado xkn
  Se f(xk)=0, então pare: x¯=xk
  Senão: dk=f(xk)+f(xk)AdkdkAdkdk
  tk=2f(xk)2dkAdk
  xk+1=xk+tkdk

Pode-se verificar facilmente que dk+1dk. De fato, como dk+1=f(xk+1)+f(xk+1)AdkdkAdkdk, tem-se Adk+1=Af(xk+1)+f(xk+1)AdkdkAdkAdk. Logo, dkAdk+1=f(xk+1)Adk+f(xk+1)AdkdkAdkdkAdk=f(xk+1)Adk+f(xk+1)Adk=0.

Predefinição:Exercício Predefinição:Resolução


Exemplos

Considere f:2 definida por f(x,y)=12(x2+y2)=12[xy][1001][xy]. Em outros termos, tomando u=[xy], tem-se f(u)=12uAu, onde A=[1001]=I2×2.

Pode-se aplicar o método de direções conjugadas ao seguinte problema

(P){minf(u)u2

Note, desde já, que o conjunto solução é S={[00]}.

Inicio
  • Toma-se x0 arbitrário, por exemplo, x0=[21].
  • Avalia-se o gradiente da função f neste ponto inicial: f(x0)=Ax0=I2×2x0=x0
Iteração 1
  • d0=f(x0)=[21]
  • t0=f(x0)2d0Ad0=55=1
  • x1=x0+t0d0=[21]+1[21]=[00]

A seguir, verifica-se se o gradiente se anula no novo ponto x1:

  • f(x1)=A[00]=[00]

Como o gradiente já é nulo, não é preciso fazer a segunda iteração, e o ponto x1 é o (único) minimizador global de f.


Em um caso mais geral, considerando f:2 definida por f(x,y)=λ2(x2+y2)=12[xy][λ00λ][xy], tem-se cálculos muito parecidos em cada passo.

O conjunto solução continua sendo S={[00]}.

Inicio
  • Considere x0 como no primeiro exemplo, ou seja, x0=[21].
  • Avalia-se o gradiente da função f neste ponto inicial: f(x0)=Ax0=λx0
Iteração 1
  • d0=f(x0)=λ[21]
  • t0=f(x0)2d0Ad0=5λ25λ3=1λ
  • x1=x0+1λλd0=[2λλ]+1[2λλ]=[00]

A seguir, verifica-se se o gradiente se anula no novo ponto x1:

  • f(x1)=A[00]=λ[00]=[00]

Novamente, o gradiente se anula já na primeira iteração, de modo que x1 é o minimizador global de f.


Predefinição:Exercício

Um terceiro exemplo pode ser dado tomando A=[2112] e f:2 definida por f(u)=12uAu. Observe que tal matriz é simétrica e definida positiva:

det(AλI)=(2λ)(3λ)1=λ24λ3=(λ3)(λ1)

Logo, os autovalores de A são λ=1 e λ=3. Isso também implica que a função é fortemente convexa.

Aplicando o método:

Início
  • Toma-se um ponto arbitrário no plano, por exemplo x0=[1020];
  • Verifica-se se tal ponto é o minimizador global, avaliando nele o gradiente da função:
f(x0)=[2112][1020]=[030]=[00].
  • Já que o gradiente não se anulou no chute inicial, é preciso escolher uma direção e um comprimento de passo para determinar a próxima aproximação:
Iteração 1
d0=f(x0)=[030]
t0=[030]2[030][2112][030]=900[030][3060]=9001800=12

Feitos esses cálculos, o próximo ponto é dado por

x1=x0+t0d0=[1020]+12[030]=[1020]+[015]=[105]

Para saber se será necessária uma nova iteração, ou se o minimizador foi encontrado, calcula-se o gradiente da função no ponto:

f(x1)=[2112][105]=[150]=[00].

Novamente, será preciso calcular uma nova direção e um novo comprimento de passo:

Iteração 2
d0=[150]+β[030]=[1530β]

onde β, no algoritmo de Hestenes é dado por:

β=[150][2112][030][030][2112][030]=[150][3060][030][3060]=15×30(30)×(60)=14

Portanto

d0=15[11/2]

Além disso, o tamanho do passo é dado por

t1=f(x1)2d0Ad0=152152[11/2][2112][11/2]=1[11/2][3/20]=13/2=23

Portanto

x2=x1+t1d1=[105]1523[11/2]=[105]10[11/2]=[00]

Obviamente, este é o minimizador procurado (pois o método tem a propriedade de convergência quadrática, ou seja utiliza no máximo n iterações para chegar a solução quando aplicado a funções quadráticas definidas em n)

Predefinição:Exercício

Predefinição:Exercício

Implementação em Scilab

Abaixo é apresentada uma implementação deste algoritmo na linguagem de programação utilizada pelo Scilab.

A = [2 1; 1 2];

function [x] = min_gradiente_conjugado(xk)
  //Entrada: xk em R^n, qualquer "chute inicial"
  //  Saída: x, o ponto em que f assume o valor mínimo
  
  k        = 0        //Indica quantos loops  foram feitos
  epsilon  = 0.01
  n        = size(xk,1)
  g        = df(xk)
  seq      = zeros(n,n+1)
  seq(:,1) = xk
  while (norm(g) > epsilon) & (k <= n)
    if (k == 0)
      d = -g
    else
      d = Hestenes(g,d,A)
    end
    t  = busca_linear(g,d,A)
    xk = xk + t*d
    k  = k+1
    seq(:,k+1) = xk
    g  = df(xk)
  end
  plot(seq(1,:),seq(2,:))
  x = xk  
endfunction


function [fu] = f(u)
  fu=(1/2)*(u'*A*u)
endfunction


function [grf] = df(u)
  grf = A*u
endfunction


function [d] = Hestenes(g,d,A)
  d=-g + ((g'*A*d)/(d'*A*d))*d
endfunction


function [t] = busca_linear(g,d,A)
  t=(g'*g)/(d'*A*d)
endfunction

Para facilitar a compreensão do método, pode ser útil exibir as curvas de nível da função. Uma forma de implementar uma função com esse propósito é a seguinte:

function plotar_curvas
  qtd=101
  tam=max(seq)
  x=linspace(-tam,tam,qtd)
  y=x
  z=zeros(qtd,qtd)
  for i=1:qtd
    for j=1:qtd
      z(i,j)=f([x(i);y(j)])
    end
  end
  contour2d(x,y,z,10)
  a=gca();
  a.x_location = "middle"; 
  a.y_location = "middle"; 
endfunction

Algoritmo de Fletcher-Reeves

Predefinição:Tarefa


Esta versão é na verdade uma extensão do algoritmo anterior, permitindo a aplicação no caso de funções que não são quadráticas.

Primeiro passo: Escolha x0n
 Se f(x0)=0, então pare: x¯=x0
 Senão: d0=f(x0) (como em todo método de descida)
 Calcular t0, através de uma busca linear
 x1=x0+t0d0
Passo iterativo:
 Se f(xk)=0, então pare: x¯=xk
 Senão: dk=f(xk)+f(xk)2f(xk1)2dk1
 Calcular tk, através de uma busca linear
 xk+1=xk+tkdk
 k=k+1

Predefinição:Tarefa

Algoritmo de Polak-Ribière

Predefinição:Tarefa

Uma outra versão é a seguinte:

Primeiro passo: Tomar x0n
 Se f(x0)=0, então pare: x¯=x0
 Senão: d0=f(x0) (como em todo método de descida)
 Calcular t0, através de uma busca linear
 x1=x0+t0d0
 k=1
Passo iterativo:
 Se f(xk)=0, então pare: x¯=xk
 Senão: dk=f(xk)+f(xk)(f(xk)f(xk1))f(xk1)2dk1
 Calcular tk, através de uma busca linear
 xk+1=xk+tkdk
 k=k+1

Predefinição:Tarefa

Predefinição:Exercício Predefinição:Exercício

Algoritmo auxiliar

Para o caso de funções não quadráticas, é preciso usar algum método de busca linear para a implementação do método dos gradientes conjugados, seja a versão de Fletcher-Reeves ou a de Polak-Ribière. Uma possibilidade é a busca de linear de Armijo (ver Izmailov & Solodov (2007), vol 2, pag. 65), cujo algoritmo é esboçado a seguir:

function busca_linear_Armijo (f, theta, alpha, delta, t0)
  while (alpha * pred > ared)
    t = d * t
  end
endfunction

com:

  • pred=tθ
  • θ(t)=f(x+td)
  • θ(t)=f(x+td)d

Predefinição:Tarefa

Predefinição:AutoCat