Article image
Ubiratan Tavares
Ubiratan Tavares05/11/2024 16:26
Compartilhe

Resolução de Equação Não-Linear Transcendental: Método de Força Bruta

  • #Python

1. Definição

O método de força bruta ou busca exaustiva é uma abordagem direta que envolve a exploração de todas as possibilidades para resolver um problema, como a busca de raízes de funções matemáticas. Este método consiste em avaliar a função em vários pontos ao longo de um intervalo para identificar onde ela cruza o eixo x, indicando a presença de uma raiz (Linge; Langtangen, 2020). Em engenharia e análise numérica, é uma opção comum quando métodos analíticos são inviáveis ou quando o espaço de busca é complexo, requerendo uma verificação exaustiva para garantir a solução (Charpa; Canale, 2020; Burden; Faires, 2011).

2. Algoritmo

O algoritmo de força bruta para encontrar raízes de uma função pode ser descrito em etapas, conforme apresentado por Linge e Langtangen (2020):

- Definir o intervalo: Escolher um intervalo [a, b] onde se suspeita que a raiz exista.

- Dividir o intervalo: Dividir o intervalo em um número fixo de subintervalos.

- Avaliar a função: Calcular o valor da função em cada ponto dos subintervalos.

- Verificar sinais: Identificar onde a função em cada ponto dos subintervalos.

- Refinar a busca: Continuar refinando a busca até que a raiz seja encontrada com a precisão desejada.

3. Vantagens

- Simplicidade: O método de força bruta é fácil de entender e implementar, tornando-o acessível para iniciantes em programação e matemática (Burden; Faires, 2011; Charpa; Canale, 2020; Linge; Langtangen, 2020; Press et al, 2007).

- Sem requisitos complexos: Não requer conhecimento prévio sobre a função, como derivadas ou continuidade, apenas a avaliação da função em pontos discretos (Linge; Langtangen, 2020). Não requer o cálculo de derivadas, o que é vantajoso para funções que são difíceis de diferenciar (Charpa; Canale, 2020).

- Generalidade: Pode ser aplicado a uma ampla gama de problemas, independentemente da complexidade da função (Burden; Faires, 2011; Charpa; Canale, 2020). Já Press et al (2007) afirma que, a aplicabilidade do método inclui aqueles problemas onde a função não é diferenciável ou onde as derivadas não estão disponíveis.

- Convergência garantida: Se a função é contínua e a raiz está dentro do intervalo escolhido, o método garantirá a identificação da raiz (Burden; Faires, 2011).

- Robustez: Funciona bem em situações onde outros métodos podem falhar, especialmente em funções com múltiplas raízes ou comportamento irregular (Press et al, 2007).

4. Limitações

- Ineficiente: O método pode ser muito ineficiente, especialmente, se a raiz está em intervalo muito grande ou se a função tiver muitas oscilações ou se a função é complexa, resultando em um número elevado de avaliações da função (Burden; Faires, 2011; Charpa; Canale, 2020; Linge; Langtangen, 2020; Press et al, 2007).

- Precisão limitada: A precisão da raiz encontrada depende da escolha do número de subintervalos; um número muito pequeno pode resultar em uma raiz imprecisa (Linge; Langtangen, 2020; Press et al, 2007). Já Burden e Faires (2011) afirmam que a precisão da solução depende da escolha do número de subintervalos, o que pode levar a um trade-off entre tempo de computação e precisão.

- Não garante a convergência: O método não garante que uma raiz será encontrada, especialmente se a função não mudar de sinal no intervalo escolhido (Linge; Langtangen, 2020). A precisão da solução pode ser baixa, e a convergência para a raiz pode ser lenta (Charpa; Canale, 2020).

- Custo computacional: O tempo de execução pode aumentar exponencialmente com o número de subintervalos, tornando-o impraticável para problemas de grande escala (Charpa; Canale, 2020). Para funções complexas, o custo computacional pode ser proibitivo, tornando outros métodos mais desejáveis (Press et al, 2007).

- Não é adaptativo

: O método não ajusta automaticamente a busca com base no comportamento da função (Burden; Faires, 2011).

5. Codificação

A implementação do método da força bruta em Python pode ser feita da seguinte forma:

import math

def calculate_step(a, b, num_points):
  return (b - a) / num_points

def are_opposite_signs(func, a, b):
  return func(a) * func(b) < 0

def brute_force(func, a, b, num_points=1000):
  roots = []
  step = calculate_step(a, b, num_points)
  for i in range(num_points + 1):
      x = a + i * step
      if are_opposite_signs(func, x, x + step):
          roots.append((x, x + step))    
  return roots

def is_list_empty(roots):
  return len(roots) == 0

def display_result(roots):
  if is_list_empty(roots):
      print("Não encontrou raíz(es) no intervalo.")
  else:
      print("Há raíz(es) no(s) sub-intervalo(s):", roots)

def function():
  return lambda x: math.exp(x) - 2  # f(x) = e^x - 2

roots = brute_force(function(), 0, 1, 100_000)
display_result(roots)

Refatorando o script acima para o paradigma de Programação Orientada a Objetos, teremos:

import math

class BruteForce:
  def __init__(self, func, a, b, num_points=1000):
      self.func = func
      self.a = a
      self.b = b
      self.num_points = num_points
      self.roots = []

  def calculate_step(self):
      return (self.b - self.a) / self.num_points

  def are_opposite_signs(self, x1, x2):
      return self.func(x1) * self.func(x2) < 0

  def find_roots(self):
      step = self.calculate_step()
      for i in range(self.num_points + 1):
          x = self.a + i * step
          if self.are_opposite_signs(x, x + step):
              self.roots.append((x, x + step))    
      return self.roots

  def is_list_empty(self):
      return len(self.roots) == 0

  def display_result(self):
      if self.is_list_empty():
          print("Não encontrou raíz(es) no intervalo.")
      else:
          print("Há raíz(es) no(s) sub-intervalo(s):", self.roots)
          
def function():
  return lambda x: math.exp(x) - 2  # f(x) = e^x - 2

finder = BruteForce(function(), 0, 1, 100_000)
finder.find_roots()
finder.display_result()

6. Discussão

O método da força bruta é uma técnica básica e de fácil implementação para encontrar raízes de funções, útil especialmente em problemas iniciais ou contextos educativos. Sua simplicidade permite aplicá-lo em situações onde métodos mais sofisticados não são viáveis (Linge; Langtangen, 2020; Chapra; Canale, 2020). No entanto, é frequentemente ineficiente e não garante convergência rápida, levando engenheiros e analistas a considerarem alternativas como o método de Newton-Raphson ou métodos híbridos, que combinam a robustez de métodos de bracketing com a velocidade dos métodos abertos (Chapra; Canale, 2020; Burden; Faires, 2011). Embora a força bruta seja vista como uma base para métodos numéricos, sua aplicação em problemas complexos é limitada pela falta de precisão e rapidez, o que torna métodos como Bisseção ou Newton preferíveis em certos contextos. Escolher bons intervalos iniciais e bracketing de raízes são práticas recomendadas para o sucesso de métodos de busca de raízes (Press et al., 2007).

7. Conclusão

O método de força bruta surge como uma abordagem fundamental, apesar de suas limitações de eficiência e precisão. Esse método direto e acessível, embora seja menos avançado, oferece uma base robusta para a introdução aos métodos numéricos e é muitas vezes o ponto de partida para estudos mais sofisticados (Linge; Langtangen, 2020). Por sua simplicidade e aplicabilidade, ele ainda é viável em diversos contextos, especialmente para iniciantes, mesmo que métodos mais avançados sejam recomendados para problemas complexos, como discutido por Chapra e Canale (2020). Essa técnica serve como um pilar para a compreensão de métodos mais complexos, e obras como as de Burden e Faires (2011) e Press et al. (2007) destacam que a familiaridade com o fundamento do método é essencial para uma aplicação mais eficaz de técnicas computacionais avançadas.

8. Referências

[1] Svein Linge; Hans Petter Langtangen. Programming for Computations - Python. Springer Open. 2020.

[2] Steven C. Chapra; Raymond P. Canale. Numerical Methods for Engineers. Eighth Edition. Mc Graw Hill. 2020.

[3] Richard L. Burden; J. Douglas Faires. Numerical Analysis. Ninth Edition. Brooks/Cole. 2011.

[4] William H. Press et al. Numerical Recipes: The Art of Scientific Computing. Third Edition. Cambridge University Press. 2007.

Compartilhe
Comentários (0)