27/28 Abril de 2004Recursividade e Iteração1 Pedro Barahona DI/FCT/UNL Abril 2004.

Slides:



Advertisements
Apresentações semelhantes
Aquiles Burlamaqui AULA 09
Advertisements

Python: Recursão Claudio Esperança.
Data: 10 a 12 de fevereiro de 2009 e
Marco Antonio Montebello Júnior
Recursividade Prof. Rosana Palazon.
1 Domínios Finitos A eficiência das programas em domínios finitos (incluindo booleanos) podem ainda ser melhoradas pelo uso de Algoritmos de Propagação.
Ludwig Krippahl, 2007 Programação para as Ciências Experimentais 2006/7 Teórica 4.
Integração Numérica – Áreas e Equações
16 Março 2006Vectores, Gráficos e Funções - Trajectória de um Projéctil1 Vectores, Gráficos e Funções Trajectória de Projéctil Pedro Barahona DI/FCT/UNL.
Vectores e Matrizes Aplicações à Engenharia
Ciclos e Funções Trajectória de Projéctil Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009.
1 Funções Trajectória de Projéctil DI/FCT/UNL 1º Semestre 2004/2005.
Funções, Execução Condicional, Recursividade e Iteração
Recursividade e Iteração Factorial, Fibonacci e Maior Divisor Comum
Ciclos, Vectores e Gráficos Simulação da Queda de Corpos II
11 de Maio de 2006Listas e Ordenação1 Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2005/2006.
Vectores, Gráficos e Funções Trajectória de um Projéctil
1 Funções, Expressões e Excepções Trajectórias Óptimas DI/FCT/UNL 1º Semestre 2004/2005.
Ciclos e Funções Trajectória de Projéctil Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2007/2008.
9 Março 2007Matrizes e Gráficos - Trajectória de um Projéctil1 Matrizes e Gráficos Trajectória de Projéctil Pedro Barahona DI/FCT/UNL Introdução aos Computadores.
Integração Numérica: Equações Diferenciais
Pesquisa e Ordenação de Vectores
2 de Junho de 2005Conclusão1 Pedro Barahona DI/FCT/UNL Junho 2005.
5 Março 2007Ciclos e Funções - Trajectória de um Projéctil1 Ciclos e Funções Trajectória de Projéctil Pedro Barahona DI/FCT/UNL Introdução aos Computadores.
Recursividade e Iteração (cont.) Processamento de Texto
Matrizes e Gráficos Trajectória de Projéctil Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 1º Semestre 2007/2008.
1 Conclusão DI/FCT/UNL 1º Semestre 2004/ Ciclos de Simulação A técnica usada no exemplo da queda livre pode ser utilizada para trajectórias a duas.
Introdução aos Computadores e à Programação
Matrizes e Gráficos Trajectória de Projéctil Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2008/2009.
Recursividade Prof. Alex F. V. Machado
1 MergeSort Seja uma lista A de n elementos. O algoritmo consiste das seguintes fases Dividir A em 2 sub-listas de tamanho n/2 Conquistar: ordenar cada.
David Menotti Algoritmos e Estruturas de Dados I DECOM – UFOP
Medida do Tempo de Execução de um Programa
Medida do Tempo de Execução de um Programa
Recursividade Conceitos e Aplicações.
Algoritmos e Programação
Meta - heurísticas Prof. Aurora
Introdução à Programação
Paradigma de Divisão e Conquista
Linguagem de Programação II Parte IX
Aula 03 – BCC202 Análise de Algoritmos (Parte 1) Túlio Toffolo www
Linguagem de programação I A Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação.
Recursão.
Indução Matemática Recursão
20/21 Abril de 2004Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004.
Algoritmos e Estruturas de Dados I – Recursão
Algoritmos e Estruturas de Dados I – Recursão
Recursão Uma função é dita recursiva quando dentro do seu código existe uma chamada para si mesma Exemplo Cálculo do fatorial de um número:
Universidade do Vale do Rio dos Sinos - São Leopoldo -
BCC 101 – Matemática Discreta I
Algoritmos e Estruturas de Dados RECURSIVIDADE. O que é recursividade? Recursividade significa algo ser definido em termos de sí próprio. Em termos de.
18/19 de Maio de 2004Registos em Ficheiros1 Pedro Barahona DI/FCT/UNL Maio 2004.
Introdução aos Computadores e Programação DI-FCT-UNL-2003/2004
Aula Prática 5 Monitoria IP/CC (~if669). Roteiro 1. 1.Recursão 2. 2.Escopo de Variáveis 3. 3.Arrays 4. 4.Strings.
Recursividade Profs. De Prog2 e Lab2.
INE Fundamentos de Matemática Discreta para a Computação
Algoritmos.
7 de Abril de 2005Funções, Expressões e Excepções1 Pedro Barahona DI/FCT/UNL Abril 2004.
Setembro 2004Projeto e Análise de Algoritmos - Celso Carneiro Ribeiro1 Projeto e Análise de Algoritmos Celso Carneiro Ribeiro
Disciplina Engenharia da Qualidade II
Elaine Teixeira de Oliveira
Trechos de código que permitem reutilização de uma mesma tarefa. Qualquer código PHP pode estar contido no interior de uma função. Não se pode definir.
Professor Luiz José Hoffmann Filho
Andréa Iabrudi 1 Universidade Federal de Ouro Preto - UFOP Departamento de Computação - DECOM Programação de Computadores I.
Linguagens de Programação Pedro Lopes MÓDULO 4- Subprogramas (Procedimentos e Funções) 2010/2011.
13/14 Abril de 2004Trajectória de um Projéctil1 Trajectória de Projéctil - Funções Pedro Barahona DI/FCT/UNL Março 2004.
Módulo I Capítulo 7: Funções e Procedimentos William Ivanski Curso de Programação C#
Trabalho e Energia O problema fundamental da dinâmica de uma partícula é saber como a partícula se move, se conhecermos a força que actua sobre ela (como.
Recursividade e análise Cristiano Arbex Valle Vinicius Fernandes dos Santos
Transcrição da apresentação:

27/28 Abril de 2004Recursividade e Iteração1 Pedro Barahona DI/FCT/UNL Abril 2004

27/28 Abril de 2004 Recursividade e Iteração 2 Programas e Funções Como visto em exemplos anteriores, um programa pode ser considerado como o encadeamento de diversas funções, isto é, no corpo de uma função são chamadas outras funções. Um programa pode pois ser estruturado de forma a ser composto por várias funções, tal como é feio na “matemática”. Por exemplo, tg(x) = sin(x) / cos(x). Em algumas linguagens de programação, nomeadamente naquelas em que as funções só podem retornar um valor, em vez de funções são usados procedimentos, mas a filosofia de encadeamento é semelhante. De notar que o programa programa principal, pode ele próprio ser visto como uma função.

27/28 Abril de 2004 Recursividade e Iteração 3 Funções Recursivas Um caso particular ocorre quando as funções se chamam a si próprias, isto é, quando as funções são recursivas. Talvez o exemplo mais simples seja o da função factorial, que pode ser definida (incompletamente) como fact(n) = n * fact(n-1) Nestas condições, tal como nos ciclos, levanta-se o problema da terminação. Se uma função se chama a si própria, existe o risco de a computação se tornar infinita (entrar em ciclo fechado ou “loop”). É pois condição necessária para evitar estes ciclos infinitos que sejam definidas e testadas em primeiro lugar as condições de fim da recursividade.

27/28 Abril de 2004 Recursividade e Iteração 4 Funções Recursivas Em geral, a recursividade é feita com base num conjunto recursivo (indutivo), definido através de cláusulas –de base; um ou vários elementos de base (que fecham a recursão) –de recursão: uma definição recursiva que permite a obtenção de elementos a partir de outros elementos. Num grande número de casos, o conjunto recursivo utilizado é o conjunto dos numeros inteiros, em que –1 (ou 0) é um número inteiro (cláusula de base) –Se i é inteiro, i+1 também é inteiro (cláusula de recursão) Tendo em conta esta estrutura recursiva, podemos definir (correctamente) a função factorial tendo em conta a cláusula de base e a cláusula recursiva

27/28 Abril de 2004 Recursividade e Iteração 5 Função Factorial A função factorial pode ser definida (em pseudo-código) como função fact(n) se n = 0 então % elemento base fact  1 senão % definição recursiva fact  n * fact(n-1) fimse; fimfunção; Em Octave, a definição é semelhante function f = fact(n); if n == 0 % elemento base f = 1 else % definição recursiva f = n * fact(n-1) endif; endfunction;

27/28 Abril de 2004 Recursividade e Iteração 6 Limites à Recursividade De notar que para prevenir os ciclos infinitos, o Octave tem uma variável prédefinida, max_recursion_depth, que limita o número de chamadas recursivas de uma função. Por omissão (“default”), o valor da variável é 256, pelo que não se pode calcular fact(260) sem alterar o valor da variável. Existem várias outras funções recursivas em que pode existir mais do que um elemento base ou em que o conjunto recursivo é mais difícil de definir. Em qualquer caso é essencial definir a condição de terminação. Para exemplificar estas funções, estudamos de seguida –a determinação dos números de Fibonacci e –o cálculo do maior divisor comum entre dois números.

27/28 Abril de 2004 Recursividade e Iteração 7 Função Fibonacci (Recursiva) Fibonacci (matemático da Renascença italiana) estabeleceu uma série curiosa de números para modelar o número de casais de coelhos em sucessivas gerações. Em cada geração, o número pode ser obtido através dos das 2 gerações anteriores através de fib(n) = fib(n-1) + fib(n-2) Assumindo que nas primeiras duas gerações só existe um casal de coelhos, os sucessivos números de Fibonacci são 1,1,2,3,5,8,13,21,34,55,89,... Estes números ocorrem em vários processos biológicos (e não só), por exemplo, no número de pétalas de algumas flores. A sua determinação recursiva impõe o cálculo directo do valor para 2 elementos de base (a 1ª e a 2ª geração).

27/28 Abril de 2004 Recursividade e Iteração 8 Função Fibonacci (Recursiva) Em Octave, a definição do números de Fibonacci pode ser feita muito facilmente como function f = fib(n); if n == 1 % 1º elemento base f = 1; elseif n == 2 % 2º elemento base f = 1; else % definição recursiva f = fib(n-1) * fib(n-2); endif; endfunction; Como é fácil de constatar, se o número n inicial fôr maior ou igual a 1, a recursão termina. No entanto, se se chamar fib(0) a computação não termina (em Octave termina quando o número de chamadas recursivas exceder o valor da variável max_recursion_depth )!

27/28 Abril de 2004 Recursividade e Iteração 9 Função Máximo Divisor Comum (Recursiva) Como se sabe, o máximo divisor comum (mdc) entre dois números m e n é também um divisor da sua diferença, m-n. Por exemplo, o mdc de 60 e 36 é 12, que divide 24 = Por outro lado, o mdc dos dois números m e n é ainda o mdc do menor número (n) com a diferença (m-n). Se houvesse um divisor comum maior, ele seria igualmente divisor de n, contrariamente à hipótese. Assim, pode determinar-se o mdc de dois números através da determinação do mdc de números cada vez menores. A computação termina quando os números forem iguais, caso em que o mdc é esse número. Por exemplo: =24 ; 36-24=12; 24-12=12; 12 = 12 !

27/28 Abril de 2004 Recursividade e Iteração 10 Função Máximo Divisor Comum (Recursiva) Em Octave, pode determinar-se o maior divisor comum de dois números com a função seguinte function d = mdc(m,n); if m == n d = m; else if m-n >= n d = mdc(m-n,n); else d = mdc(n,m-n); endif; endfunction; De notar que na chamada, o 1º argumento (m) é sempre maior ou igual que o 2º (n), de forma a garantir que m-n seja positivo!

27/28 Abril de 2004 Recursividade e Iteração 11 Recursão e Iteração Em geral, uma função ou procedimento definidos recursivamente podem-no ser tambem de uma forma iterativa (através de ciclos). Em geral, a definição recursiva é mais “declarativa” na medida em que explicita o que se pretende obter e não a forma como se obtem (ou seja, um determinado programa que é usado). Por outro lado, uma definição iterativa, embora não permita uma compreensão tão imediata, é geralmente mais eficiente, já que as instruções de programação de baixo nível para a iteração são mais eficientes que as de chamadas de funções. No entanto, estas diferenças são geralmente pouco importantes, excepto em casos de recursão múltipla, em que a ineficiência pode ser “catastrófica”.

27/28 Abril de 2004 Recursividade e Iteração 12 Recursão e Iteração function f = fib(n); % versão recursiva if n <= 2 f = 1; else f = fib(n-1) + fib(n-2); endif; endfunction; function f = fib(n) % versão iterativa if n <= 2 f = 1; else f1 = 1; f2 = 1; for i = 3:n f = f1+f2; f1 = f2; f2 = f; endfor; endif; endfunction;

27/28 Abril de 2004 Recursividade e Iteração 13 Recursão e Iteração Esta é a situação da função de Fibonacci, em que o seu valor depende de 2 chamadas recursivas. Como as chamadas são independentes, a mesma função acaba por ser recalculada várias (muitas !) vezes Na realidade, o número de funções chamadas é o próprio número de fibonacci (7:1, 6:1, 5:2, 4:3, 3:5, 2:8) que aumenta exponencialmente com o valor de n.

27/28 Abril de 2004 Recursividade e Iteração 14 Recursão e Iteração Para se ter uma ideia do aumento, podemos notar que apesar de inicialmente pequenos os números tornam-se rapidamente “enormes” tornando proibitiva a sua computação recursiva (normal).

27/28 Abril de 2004 Recursividade e Iteração 15 Memorização Por vezes é possível aliar a declaratividade da versão recursiva, com a eficiência da versão iterativa, através da memorização dos valores já computados. Por exemplo se se pretenderem os primeiros 100 números de fibonacci, pode criar-se uma tabela, fib_m, com os valores já computados. –Se fib_m(n) ainda não contiver o valor de fib(n), então determina-se fib(n) e escreve-se em fib_m(n). –Caso contrário, apenas se retorna o valor de fib_m(n). Para que este esquema seja posível, é conveniente que a tabela fib_m seja visível por todas as instâncias da função fib(n). Para evitar passá-la como parâmetro deve declarar-se como uma variável global.

27/28 Abril de 2004 Recursividade e Iteração 16 Variáveis Globais em Octave Em Octave, para que uma variável seja global, ela deve ser declarada no programa principal com a declaração global. No caso actual, se se pretende um vector linha com 100 elementos inicializados a zero, devemos declarar a variável global global fib_m = zeros(1,100) Uma vez declarada uma variável global, ela só pode ser eliminada através da declaração clear. Se pretendermos um vector com 200 elementos deveremos fazer clear fib_m global fib_m = zeros(1,100) Para que na função a variável, fib_m considerada seja a variável global e não uma variável local, a variável deve ser identificada novamente como global.

27/28 Abril de 2004 Recursividade e Iteração 17 Memorização function f = fib(n); % versão recursiva com memória global fib_m; if fib_m(n) > 0 f = fib_m(n); else if n <= 2 f = 1; else fib_m(n) = fib_mem(n-1)+fib_mem(n-2); f = fib_m(n); endif; endfunction;

27/28 Abril de 2004 Recursividade e Iteração 18 Recursividade para Resolução de Problemas A recursividade pode ser usada na resolução de problemas, difíceis de resolver por outras técnicas de programação. Tal é o caso das “Torres de Hanoi”: dadas três torres (estacas) pretende-se passar uma “pirâmide” de peças ordenadas de uma torre para outra, movendo-se uma peça de cada vez, para o topo de uma torre encimada por uma peça menor.

27/28 Abril de 2004 Recursividade e Iteração 19 Apesar de aparentemente complicado, este problema tem uma solução recursiva simples. Para passar n peças de uma torre (A) para outra (C) 1.Passar n-1 peças da torre inicial (A) para a torre livre (B) 2.Mover a última peça, para a torre final (C) 3.Passar as n-1 peças da torre B para a torre final (C). Torres de Hanoi - Recursividade

27/28 Abril de 2004 Recursividade e Iteração 20 Torres de Hanoi: Movimentos Necessários Baseados nesta resolução recursiva podemos –Determinar o número de movimentos necessários –Determinar os movimentos necessários O número de movimentos necessários é bastante simples de determinar, na versão recursiva hanoi_count(n) = hanoi_count(n-1)+1+ hanoi_count(n-1) Há no entanto que evitar a dupla recursividade, o que neste caso é imediato hanoi_count(n) = 2*hanoi_count(n-1) + 1 Finalmente, há que especificar a condição de paragem (n=1) hanoi_count(1) = 1

27/28 Abril de 2004 Recursividade e Iteração 21 Torres de Hanoi: Movimentos Necessários Um programa Octave para resolver o programa é imediato function c = hanoi_count(n) if n == 1 c = 1; else c = 2*n_hanoi_count(n-1)+1; end; endfunction; De notar o aumento exponencial do número de movimentos necessários

27/28 Abril de 2004 Recursividade e Iteração 22 Torres de Hanoi O problema propriamente dito pode ser resolvido com base num vector T, com 3 números, correspondentes ao número de peças em cada uma das torres. Notar que não é necessário indicar o tamanho de cada peça, porque o algoritmo nunca coloca uma peça sobre uma menor! O movimento de uma só peça da torre A para a torre B, usado no corpo da recursão e na sua terminação, pode ser feito com uma função auxiliar, move_hanoi(T,A,B), especificada da forma óbvia (tira uma peça de A e aumenta em B). T = [3,1,1]

27/28 Abril de 2004 Recursividade e Iteração 23 Torres de Hanoi function T = hanoi(T,N,A,B) % move N peças de A para B if N == 1 T = hanoi_move(T,A,B); % move a peça de A para B else C = 6-A-B; % C é a outra torre! T = hanoi(T,N-1,A,C); % move N-1 peças de A para C T = hanoi_move (T,A,B); % move 1 peça de A para B T = hanoi(T,N-1,C,B); % move N-1 peças de C para B end; endfunction; function T = hanoi_move(T,A,B) T(A) = T(A) - 1; T(B) = T(B) + 1; disp(T); endfunction;

27/28 Abril de 2004 Recursividade e Iteração 24 O funcionamento do programa pode ser visto com a chamada >> hanoi([4,0,0],4,1,3); Torres de Hanoi hanoi(_,2,1,3) hanoi(_,2,3,2) hanoi(_,3,1,2) move(_,1,2) hanoi(_,2,2,1) hanoi(_,2,1,3) hanoi(_,3,2,3) move(_,2,3) move(_,1,3)