Capítulo VII : A Recorrência

Documentos relacionados
Métodos de Programação I Ana Maria de Almeida 92. Um objecto (uma função, um método) diz-se recorrente se é definido em termos de si próprio.

Métodos de Programação I Ana Maria de Almeida

termo Para resolver o problema, basta construir um Módulo (procedimento) para cada uma das definições: factor termo enquanto '+' ou '-'

Capítulo V : A Linguagem Pascal Um Tipo Estruturado de Dados: o array 18. Para limite de n até 2 (* passagens de 1 até (n-1) *)

Capítulo VI : Subprogramas

Capítulo V : Um Tipo Estruturado de Dados: o array

Análise e Desenvolvimento de Algoritmos (2006/2007)

tipoveiculo = (bicicleta, motociclo, motorizada, automovel, autocomreb, camioneta, autocarro, camiao, reboque); veiculo : tipoveiculo;

Introdução à Computação II Unesp Rio Claro 2012Prof. Rafael Oliveira

Linguagem Pascal. Prof. Antonio Almeida de Barros Junior

Recursão. Prof. Cristiano André da Costa. [Versão de Março de 2000] Definição

Algoritmo e Programação Matemática

Sintaxe do Pascal Simplificado Estendido de 12 novas construções em Notação EBNF (BNF estendida)

Métodos de Programação I Ana Maria de Almeida

Pascal. -Cabeçalho do programa. - label - const - type - var - procedure - function. - integer - real - byte - boolean - char - string

Tipos de Dados Dinâmicos

2.2.5 EXPRESSÕES - Regras para o cálculo de valores

Folha 4.2 Análise sintática ascendente

Procedimento. Função. Selecção Condicional - a instrução if-then-else. expressão if lógica then instrução else instrução

Computação Eletrônica

Linguagem de programação: Pascal

3. 1. Teste no Início do Ciclo (Repetição enquanto ):

Aula 21 - Algoritmos e Funções Recursivas

Exercícios sobre o Capítulo III

Programação Estruturada

Programação Introdução

Modularidade. Objetivos: Introduzir noções básicas de modularidade. Funções e procedimentos

Aula prática 5. Funções Recursivas

Aulas Anteriores. Detalhes da linguagem de programação

SCC 202 Algoritmos e Estruturas de Dados I. Pilhas (Stacks) (implementação dinâmica)

= = = = = = = = = = = = = = = =

SCC Capítulo 2 Recursão

Recursividade. Recursividade

Exemplos de programação em PASCAL

É interessante comparar algoritmos para valores grandes de n. Para valores pequenos de n, mesmo um algoritmo ineficiente não custa muito para ser

1.2 OPERAÇÕES BÁSICAS EM ALGORITMOS E PROGRAMAS 18

UNISINOS - UNIVERSIDADE DO VALE DO RIO DOS SINOS CENTRO DE CIÊNCIAS EXATAS E TECNOLÓGICAS (C6/6) Curso: Informática

Linguagem Pascal. Prof. Sérgio Rodrigues. É a descrição, de forma lógica, dos passos a serem executados no cumprimento de determinada tarefa;

Aula Anterior. Decomposição algorítmica (continuação)

Introdução à Ciência da Computação

INTRODUÇÃO À LINGUAGEM PASCAL PREFÁCIO

Programando o Computador com PascaL: um ambiente para Auto-Aprendizagem.

Introdução à Programação em C

SCC0601 Projeto de Algoritmos. Recursão

Lista 13. Program Pzim ; var dez : array [ ] of real; i:integer; Begin //lê 10 valores for i:= 1 to 10 do readln(dez[i]); //calcula

Métodos de Ordenamento e

Curso Técnico de Mecatrônica 4º Ano 2º Bimestre Introdução à Lógica de Programação

Tipo m= matriz [ l i1 : l s1, l i2 : l s2 ] <tipo básico> m: mat

Métodos de Programação I Ana Maria de Almeida

Fernando Silva DCC-FCUP. Estruturas de Dados

Resolução De Problemas Em Informática. Docente: Ana Paula Afonso Resolução de Problemas. 1. Analisar o problema

Linguagem e Técnicas em Programação. Gilson de Souza Carvalho

Números Inteiros Algoritmo da Divisão e suas Aplicações

Conjunto (set) O tipo estruturado set representa, em Pascal, um conjunto de objectos de um dado tipo;

Análise Semântica e Tratamento de Erros Dependentes de Contexto

Linguagem Pascal. Prof. Jonatas Bastos Site:

Recursão. Introdução à Ciência da Computação II(2009/2010) Rosane Minghim. Apoio na confecção: Rogério Eduardo Garcia Danilo Medeiros Eler

Teoria da Computação e Algoritmos. Introdução à Linguagem Pascal. ALGORITMO <Nome do algoritmo>; <definições>; INÍCIO <Comandos>; FIM.

Linguagem Computacional

Algoritmos e Programação

O AMBIENTE DE PROGRAMAÇÃO VISUAL -PLANO DE ENSINO. Prof. Angelo Augusto Frozza, M.Sc.

Capítulo III : A Linguagem Pascal Estruturas de Controlo

Linguagem Computacional. Estruturas de Controle: Estruturas de Repetição. Prof. Dr. Adriano Cansian Prof. Dr. Leandro Alves Neves

Um algoritmo deve conter passos não ambíguos, executáveis e que sejam terminados quando seguidos.

Aula 15 Variáveis Indexadas (vetores)

Recursão. Definição. Características. Recursividade 31/08/2010

Arquitetura Von Neumann Dados e instruções são obtidos da mesma forma, simplificando o desenho do microprocessador;

Aula 1. Teoria da Computação III

SEBENTA INTRODUÇÃO Á ALGORITMIA

Introdução à Programação 2006/07. Algoritmos

Linguagens de Programação

Linguagem Pascal. Definição e Tipos de Dados. Professora Lara Popov Zambiasi Bazzi Oberderder. Linguagem PASCAL 1

Estruturas de Dados, Análise de Algoritmos e Complexidade Estrutural. Carlos Alberto Alonso Sanches

I1, I2 e In são instruções simples ou estruturadas da linguagem Pascal.

Refinamentos sucessivos

Linguagens de Programação

Linguagens de Programação

Estrutura de um Algoritmo, Variáveis, Comandos de Entrada e Saída e Expressões Aritméticas

Exemplos. Alocação Dinâmica de Pilhas. Pilhas. Pilhas. Implementação Seqüencial X Encadeada. SCE 182 Algoritmos e Estruturas de Dados I

ALGORITMOS VARIÁVEIS E OPERADORES. Prof. Angelo Augusto Frozza, M.Sc.

BCC Introdu c ao ` a Programa c ao Portugol Guillermo C amara-ch avez UFOP 1/35

Recursão David Déharbe

Lista de Figuras Figura 1 1: Figura 1 2: Figura 1 3: Figura 1 4: Figura 1 5: Figura 1 6: Figura 1 7: Figura 2 1: Figura 2 2: Figura 2 3: Figura 2 4:

Layout. Módulos. Normalmente, cada módulo está armazenado num ficheiro com o mesmo nome do módulo. Exemplo.hs

LÓGICA DE PROGRAMAÇÃO. Algoritmos Computacionais. Sérgio Carlos Portari Júnior

EXPRESSÕES ARITMÉTICAS PARTE 1

Processamento da Informação

Departamento de Engenharia Rural Centro de Ciências Agrárias. Programação I

Pesquisa: operação elementar

Elementos básicos das linguagens de programação

Texto retirado e adaptado da apostila Curso de Linguagem Pascal, disponível no site (autor: desconhecido).

Aula 10: Introdução a Vetores e Matrizes

TÉCNICO DE INFORMÁTICA - SISTEMAS

Curso Profissional de Gestão e Programação de Sistemas Informáticos. Programação e Sistemas de Informação. Módulo 1. 3ª Parte Prof. Sandra Pais Soares

Linguagem e Técnicas em Programação. Gilson de Souza Carvalho

Linguagem e Técnicas em Programação. Gilson de Souza Carvalho

Transcrição:

Capítulo VII : A Recorrência 1 _ Capítulo VII : A Recorrência Quando algo é definido em termos de si próprio. Ex1: O Tetraedro de Sierpinski Ex2: Fracções Contínuas Ex3: A Carpete de Sierpinski Ex4: A Instrução Composta em Pascal

Capítulo VII : A Recorrência 2 _ Ex5: A Função Factorial n! = n (n 1)! 1 se se n n > = 0 0 Algoritmo Recorrente: n 0 se n = 0 então n! 1 senão n! n * (n-1)! Função Pascal Recorrente: function factorial (n : intnneg) : intnneg; begin if n=0 then factorial:= 1 else factorial:= n * factorial(n-1) end; Atribuição do Valor ao Identificador da Função (sem o Parâmetro) Chamada da Função numa Expressão (com o Parâmetro) O Bloco da Função pertence ao Domínio do seu Identificador. Por isso, é possível utilizar esse Identificador (Chamar a própria Função) dentro do Bloco da sua Declaração.

Capítulo VII : A Recorrência 3 _ Simulação: factorial(4) n=4 factorial 4 * factorial(3) n=3 factorial 3 * factorial(2) n=2 factorial 2 * factorial(1) n=1 factorial 1 * factorial(0) n=0 factorial 1 factorial 1 * 1 = 1 factorial 2 * 1 = 2 factorial 3 * 2 = 6 factorial 4 * 6 = 24 Comentários: Número de Chamadas da Função: n+1 Número de Multiplicações: n Espaço de Memória utilizado: Cada Chamada gera uma cópia do Parâmetro n (da Classe Valor); O Valor de factorial, calculado por cada Chamada da Função, ocupa um Registo de Memória; Total: 2(n+1) A utilização da Recorrência no cálculo da Função Factorial: Conduz a uma solução simples e elegante; É pouco eficiente, em particular, em termos da Memória utilizada. (Ver Cap. VI, pág. 27)

Capítulo VII : A Recorrência 4 _ Ainda menos eficiente... Ex6: A Sucessão de Fibonacci 1, 1, 2, 3, 5, 8, 13, 21, 34,... F n = F n-2 + F n-1 se n > 2 F 1 = F 2 = 1 Função Pascal Recorrente: function fibonacci (n : intpos) : intpos; begin if n<=2 then fibonacci:= 1 else fibonacci:= fibonacci(n-2) + fibonacci(n-1) end; Simulação: F(6) = 8 F(6) F(4) + F(5) F(2) + F(3) F(3) + F(4) 1 + F(1) + F(2) + F(1) + F(2) + F(2) + F(3) 1 + 1 + 1 + 1 + 1 + 1 + F(1) + F(2) 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1

Capítulo VII : A Recorrência 5 _ Comentários: Solução simples, clara e elegante; Mesmo nada eficiente, nem em termos das Operações realizadas, nem do número de Chamadas, nem da utilização de Memória; A definição recorrente pode contudo facilitar a elaboração de uma solução iterativa eficiente. Exercício: Versão iterativa só com 3 variáveis. A versão recorrente de um Algoritmo é, por vezes, mais clara e concisa do que a correspondente versão iterativa. Como, por exemplo: Ex7: Algoritmo de Euclides O Algoritmo de Euclides, para o cálculo do Máximo Divisor Comum de dois números inteiros não-negativos, baseia-se nas seguintes Propriedades: mdc(a,b) = mdc(b, a mod b) se b 0 mdc(a,0) = a Função Pascal Recorrente: function mdc (a, b : intnneg) : intnneg; begin if b = 0 then mdc:= a else mdc:= mdc(b, a mod b) end; A solução Recorrente é mais clara do que a versão Iterativa e mais fácil de elaborar, directamente a partir da teoria; A perda de eficiência é, neste caso, compensada pela Clareza.

Capítulo VII : A Recorrência 6 _ O modo de utilização de Memória das soluções Recorrentes pode tornar-se bastante útil... Ex8: Inverter uma palavra Ler uma palavra, terminada por um espaço, e escrever as suas letras por ordem inversa. Algoritmo Iterativo: ler cada letra, até espaço, registando num vector; escrever letras por ordem inversa. S T A R (Desperdício de espaço de Memória, provocado pela declaração do vector) Algoritmo Recorrente: ler uma letra; se letra espaço então Inverter o resto da palavra; escrever letra. Procedimento Pascal Recorrente: procedure inverter; var letra : char; begin read(letra); if letra <> ' ' then inverter; write(letra:1) end;

Capítulo VII : A Recorrência 7 _ Simulação: inverter: ler('s'); inverter: ler('t'); inverter: ler('a'); inverter: ler('r'); inverter: ler(' '); escrever(' '); escrever('r'); escrever('a'); escrever('t'); escrever('s'); Espaço de Memória utilizado: # letras + 1 Cada chamada gera uma cópia da variável local letra, onde são registadas as sucessivas letras da palavra. Neste caso, a versão recorrente é mais eficiente, em termos de utilização de memória. Ex9: Inverter um número Escrever, por ordem inversa, os dígitos de um dado inteiro positivo. Algoritmo Recorrente: escrever o último dígito (unidades); se restarem dígitos então Inverter o resto do número. Procedimento Pascal Recorrente: procedure inverter(numero : intpos); begin write(numero mod 10 : 1); if (numero div 10) <> 0 then inverter(numero div 10) end;

Capítulo VII : A Recorrência 8 _ A solução recorrente de um problema é, por vezes, a mais fácil... Ex10: Torres de Hanoi (Edouard Lucas, 1883) Deslocar os (7) discos da Torre A para a Torre C, um de cada vez. Utilizar a Torre B como auxiliar, mas nunca colocar um disco, sobre outro menor. Algoritmo Recorrente: n = 1 : sabemos deslocar 1 disco; Como deslocaríamos n discos, se soubessemos deslocar n-1 discos? (n-1) discos 1 disco (n-1) discos

Capítulo VII : A Recorrência 9 _ Portanto: Mover n discos de A para C, usando B como auxiliar: Mover n-1 discos de A para B, usando C como auxiliar; Mover 1 disco de A para C; Mover n-1 discos de B para C, usando A como auxiliar. Ou, melhor: MoverTorre(n, origem, auxiliar, destino): MoverTorre(n-1, origem, destino, auxiliar); MoverDisco(origem, destino); MoverTorre(n-1, auxiliar, origem, destino). Programa Pascal: program TorresdeHanoi(input, output); type torre = 'A'..'C'; intnneg = 0..maxint; var n : intnneg; procedure MoverDisco(desde, para : torre); begin writeln(desde:1, ' >', para:1) end; procedure MoverTorre(n : intnneg; origem, auxiliar, destino : torre); begin if n>1 then begin MoverTorre(n-1, origem, destino, auxiliar); MoverDisco(origem, destino); MoverTorre(n-1, auxiliar, origem, destino) end else MoverDisco(origem, destino) end; begin writeln('quantos discos tem a Torre de Hanoi?'); readln(n); MoverTorre(n, 'A', 'B', 'C') end.

Capítulo VII : A Recorrência 10 _ Simulação: MoverTorre(3, A, B, C): MoverTorre(2, A, C, B): MoverTorre(1, A, B, C): MoverDisco(A, C); MoverDisco(A, B); MoverTorre(1, C, A, B): MoverDisco(C, B); MoverDisco(A, C); MoverTorre(2, B, A, C): MoverTorre(1, B, C, A): MoverDisco(B, A); MoverDisco(B, C); MoverTorre(1, A, B, C): MoverDisco(A, C); Teorema: O número de Movimentos simples necessários para mover uma Torre de Hanoi com n discos: M(n) = 2 n - 1 Demonstrar: ( Por Indução...)

Capítulo VII : A Recorrência 11 _ Exercícios: Elabore um algoritmo recorrente para calcular M(n). Elabore um algoritmo iterativo para calcular M(n). Questões associadas à lenda das Torres de Hanoi: Se um monge budista demorar um segundo para deslocar um disco, quanto tempo será necessário para mover a Torre completa (64 discos)? Qual o valor estimado para a esperança de vida do Sol? Construir a solução iterativa do problema das Torres de Hanoi. A Construção de Soluções Recorrentes: 1. Como definir o problema em termos de um problema menor e do mesmo tipo? 2. Como diminui o tamanho do problema, em cada chamada recorrente? 3. Qual o caso particular do problema, que pode servir para a paragem? Verificar se o modo como diminui o tamanho do problema, em cada chamada, assegura que o caso base (paragem) é sempre atingido. Exercícios: Elaborar soluções puramente recorrentes para contruir cada uma das figuras seguintes (não utilizar nenhum ciclo). 1 1 2 1 1 2 3 2 1 1 2 3 4 3 2 1 1 2 3 4 5 4 3 2 1 1 2 3 4 5 6 5 4 3 2 1 1 1 2 1 1 2 3 2 1 1 2 3 4 3 2 1 1 2 3 4 5 4 3 2 1 1 2 3 4 3 2 1 1 2 3 2 1 1 2 1 1

Capítulo VII : A Recorrência 12 _ Em certos casos, quando não é conhecido um algoritmo iterativo, é necessário gerar um processo recorrente de Pesquisa Exaustiva (Backtracking). Ex11: O Problema da 8 Rainhas Num tabuleiro de Xadrez, a Rainha domina toda a linha, a coluna e as duas diagonais da casa onde estiver colocada. Como colocar 8 Rainhas (não dominadas) num tabuleiro? (Existem 92 soluções possíveis) Processo de Backtracking: Tentar pôr Rainha na linha (i): para cada coluna j se a casa [i, j] estiver livre pôr Rainha na casa [i, j] i < 8 i = 8 Tentar pôr Rainha na linha (i+1) Imprimir Solução retirar Rainha da casa [i, j]

Capítulo VII : A Recorrência 13 _ Como assinalar as casas que estão, ou não, livres? Consideremos um conjunto de vectores do tipo boolean, onde: true casa livre false casa dominada Para as colunas: var a : array [1..8] of boolean; Para as diagonais ascendentes (i+j): Para as diagonais descendentes (i-j): var b : array [2..16] of boolean; var c : array [-7..7] of boolean; O processo tenta, sucessivamente, colocar uma Rainha em cada linha. Para registar a posição (coluna) ocupada por cada Rainha basta: var x : array [1..8] of 1..8;

Capítulo VII : A Recorrência 14 _ program OitoRainhas(input, output); type linha, coluna = 1..8; var a : array [coluna] of boolean; var b : array [2..16] of boolean; var c : array [-7..7] of boolean; var x : array [linha] of coluna; var i : integer; procedure EscreverSolucao; begin... (* Como? *)... end; procedure Tentar(i : linha); var j : coluna; begin for j:= 1 to 8 do if a[j] and b[i+j] and c[i-j] then begin (* Pôr Rainha em [i, j] *) x[i]:= j; a[j]:= false; b[i+j]:= false; c[i-j]:= false; if i<8 then Tentar(i+1) else EscreverSolucao; (* Retirar Rainha de [i, j] *) x[i]:= 0; a[j]:= true; b[i+j]:= true; c[i-j]:= true end end (* Tentar *); begin for i:= 1 to 8 do a[i]:= true; for i:= 2 to 16 do b[i]:= true; for i:= -7 to 7 do c[i]:= true; for i:= 1 to 8 do x[i]:= 0; Tentar(1) end.

Capítulo VII : A Recorrência 15 _ Exercício: Circuito de Cavalo Outro problema clássico associado ao Xadrez consiste em, partindo de uma dada casa e sempre em Salto de Cavalo, percorrer cada uma das casas do tabuleiro uma só vez, acabando na casa inicial. Construa uma Solução Recorrente para este problema. Problemas que permitem uma definição recorrente, conduzem naturalmente a soluções recorrentes... Ex12: Notação Polaca (Lukasiewicz, 1878-1956) Na notação habitual ( infix ) das Expressões Aritméticas, cada operador é colocado entre os dois operandos correspondentes. a + b * c Para saber a ordem por que são efectuados os cálculos, é necessário estabelecer um conjunto de Regras de Prioridade entre os operadores e (para alterar essa ordem) é também necessário o uso de Parênteses. Na Notação Polaca ( postfix ), cada operador é colocado depois dos dois operandos correspondentes. A ordem dos cálculos a efectuar fica univocamente definida, sem Regras de Prioridade nem Parênteses.

Capítulo VII : A Recorrência 16 _ Exemplos: infix postfix a + b a b + (a + b) * c a b + c * (a + b) * (c - d) a b + c d - * a + b * c - d a b c * + d - a + b * (c - d) a b c d - * + (a + b) * c - d a b + c * d - A Notação Polaca é utilizada na Compilação das Expressões Aritméticas escritas nas Linguagens de Alto Nível. Problema: Conversão infix postfix Vamos considerar uma Linguagem de Alto Nível, que consiste numa simplificação da Linguagem Pascal. Definições: Expressão: Termo: Factor: Identificador: