Funcoes Recursivas
Enviado: 10 Abr 2023 19:43
Recentemente, estava trabalhando com funcoes recursivas e me deparei com o custo de processamento da maquina. Utilizando uma determinada funcao recursiva, num "FOR" de 1 ate 40, tinha um tempo de processamento muito longo.
Pesquisando sobre o assunto, encontrei dois alguritmos que me ajudaram bastante em relacao ao custo computacional.
Compartilhando aqui.
Espero que ajude alguem.
Pesquisando sobre o assunto, encontrei dois alguritmos que me ajudaram bastante em relacao ao custo computacional.
Compartilhando aqui.
Espero que ajude alguem.
Código: Selecionar todos
/**
A implementacao recursiva padrao da funcao Fibonacci eh muito ineficiente
para valores grandes de n, pois pode levar a um grande numero de chamadas
recursivas de funcao e a um alto consumo de memoria. No entanto, existem
outras implementacoes da funcao Fibonacci que sao mais eficientes e podem
calcular os valores da sequencia de Fibonacci com muito menos recursos
computacionais.
Algoritmo de matriz:
Este algoritmo usa matrizes para calcular os valores de Fibonacci
em tempo constante. A ideia basica eh usar uma matriz de 2x2 para
representar o valor atual da sequencia de Fibonacci e o valor
anterior, e aplicar uma formula matematica para calcular o proximo
valor da sequencia. Esse algoritmo eh muito mais eficiente do que a
implementacao recursiva padrao, pois evita chamadas recursivas de
funcao e usa apenas um pequeno numero de operacoes matematicas para
calcular cada valor.
Algoritmo de tempo constante:
Este algoritmo calcula os valores de Fibonacci em tempo constante,
usando apenas algumas operacoes matematicas simples. A ideia basica
eh armazenar o valor atual da sequencia de Fibonacci e o valor
anterior em duas variaveis e, em seguida, atualizar as variaveis a
cada iteracao do loop para calcular o proximo valor da sequencia.
Esse algoritmo eh ainda mais eficiente do que o algoritmo de matriz,
pois usa apenas algumas operacoes matematicas simples para calcular
cada valor.
Ambos os algoritmos sao muito mais eficientes do que a implementacao
recursiva padrao da funcao Fibonacci e podem calcular os valores da
sequencia de Fibonacci com muito menos recursos computacionais. Isso
torna esses algoritmos ideais para valores grandes de n, onde a
implementacao recursiva pode levar a um tempo de execucao muito longo
ou ate mesmo a um estouro de pilha.
**/
FUNCTION Main()
LOCAL tInicio, tFinal, tProcesso, i, nResultado
tInicio := time()
// ? "Hora inicial:", tInicio
// *** Use esse FOR com a funcao padrao. Demora cerca de 1 a 2 minutos
//
// FOR i := 1 TO 40
// nResultado := fib(i)
// ? "fibonacci(" + ALLTRIM(STR(i)) + ") = " + ALLTRIM(STR(nResultado))
// NEXT
// *** Use esse for com 400 para testar os algoritmos de Matriz e Tempo
FOR i := 1 TO 400
nResultado := fib_matriz(i)
// nResultado := fib_tempo(i)
? "fibonacci(" + ALLTRIM(STR(i)) + ") = " + ALLTRIM(STR(nResultado))
NEXT
tFinal := time()
tProcesso := ELAPTIME(tInicio, tFinal)
? "Hora inicial :", tInicio
? "Hora final :", tFinal
? "Tempo do Processo:", tProcesso
RETURN Nil
// Algoritmo Padrao
FUNCTION fib(n)
RETURN (IIF( n > 1, fib(n-1) + fib(n-2), n))
// Algoritmo de Matriz
FUNCTION fib_matriz(n)
LOCAL aMatriz, aResultado
IF (n <= 1)
RETURN n
ENDIF
aMatriz := {{1, 1}, {1, 0}}
aResultado := matriz_pow(aMatriz, n-1)
RETURN aResultado[1, 1]
FUNCTION matriz_mul(a, b)
LOCAL c, i, j
c := {{0, 0}, {0, 0}}
FOR i := 1 TO 2
FOR j := 1 TO 2
c[i, j] := a[i, 1] * b[1, j] + a[i, 2] * b[2, j]
NEXT
NEXT
RETURN c
FUNCTION matriz_pow(a, n)
LOCAL b
IF (n == 1)
RETURN a
ELSEIF ((n % 2) == 0)
b := matriz_pow(a, n/2)
RETURN matriz_mul(b, b)
ELSE
b := matriz_pow(a, (n-1)/2)
RETURN matriz_mul(matriz_mul(b, b), a)
ENDIF
// Algoritmo de Tempo Constante
FUNCTION fib_tempo_const(n)
LOCAL fib_antigo, fib_atual, fib_prox, i
IF (n <= 1)
RETURN n
ENDIF
fib_antigo := 0
fib_atual := 1
FOR i := 2 TO n
fib_prox := fib_atual + fib_antigo
fib_antigo := fib_atual
fib_atual := fib_prox
NEXT
RETURN fib_atual