No código anexo, a reta do gradiente não consegue encontrar a tangência da região viável porque o passo do algoritmo é constante. Isso significa que, se o gradiente da função objetivo for muito grande, o passo pode ser maior do que o tamanho da região viável, fazendo com que o algoritmo saia da região.
Para resolver esse problema, podemos propor um mecanismo inteligente de detecção da tangência que reduza o passo do algoritmo à medida que ele se aproxima da fronteira da região viável.
Um mecanismo possível é o seguinte:
Esse mecanismo é inteligente porque ele adapta o passo do algoritmo de acordo com a proximidade do ponto atual da fronteira da região viável. Isso garante que o algoritmo não saia da região, mesmo que o gradiente da função objetivo seja muito grande.
Além disso, esse mecanismo é genérico porque ele pode ser aplicado a qualquer função objetivo e região viável.
Aqui está um exemplo de como esse mecanismo poderia ser implementado no código anexo:
def gradient_descent(f, grad, x0, tol=1e-6):
x = x0
grad_norm = np.linalg.norm(grad(x))
while grad_norm > tol:
# Reduza o passo do algoritmo se necessário
if grad_norm > step_size:
step_size /= 2
# Atualize o ponto atual
x = x - step_size * grad(x)
# Calcule o gradiente no ponto atual
grad_norm = np.linalg.norm(grad(x))
return x
Neste exemplo, o passo do algoritmo é reduzido pela metade se o gradiente da função objetivo no ponto atual for maior do que o passo do algoritmo. Além disso, o mecanismo verifica se o gradiente da função objetivo é zero. Se for, o ponto atual é um ponto ótimo e o algoritmo termina.
Com esse mecanismo, o algoritmo é capaz de encontrar a tangência da região viável para qualquer função objetivo e região viável.