Sie sind auf Seite 1von 38

Algoritmos e Complexidade

LEI 2.1, 2013-14 Equipa Docente: Jorge Sousa Pinto (coordenador) Atendimento: 6a.fa. 11:0013:00 Maria Jo ao Frade Jos e Bernardo Barros Apoio na Web via Blackboard jsp@di.uminho.pt

mjf@di.uminho.pt jbb@di.uminho.pt

Programa Resumido

I. Introdu c ao ` a An alise de Correc c ao de Algoritmos II. An alise de Tempo de Execu c ao de Algoritmos III. Estruturas de Dados Fundamentais: quest oes de eci encia na pesquisa; IV. Algoritmos Fundamentais sobre Grafos V. Problemas NP-completos

Avalia c ao

Epoca normal: NF = .5 Teste1 + .5 Teste2 Nota m nima de 5 valores (em 20) em ambos os testes. Exame recurso sobre toda a mat eria Estrutura dos testes e exame: Parte A: 75% valores de compet encias m nimas Parte B: 25% valores de compet encias complementares Ao contr ario de edi c oes anteriores, a aprova c ao n ao implica qualquer nota m nima na parte A.
3

Bibliograa Recomendada

[1] Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Cliord Stein. Introduction to Algorithms. MIT Press, Cambridge, Mass., third edition, 2009. [2] Robert L. Kruse, Bruce P. Leung, and Clovis L. Tondo. Data Structures and Program Design in C. Prentice Hall, second edition, 1997. [3] Donald E. Knuth. The Art of Computer Programming : (1) Fundamental Algorithms, (2) Seminumerical Algorithms, (3) Sorting and Searching (4) Combinatorial Algorithms. AddisonWesley, 19972011.

O que e um algoritmo?
Um algoritmo e um procedimento computacional bem denido que aceita um valor (ou conjunto de valores) como input e produz um valor (ou conjunto de valores) como output. Deni c oes alternativas: uma sequ encia de passos computacionais que transformam um input num output. um m etodo para resolver um problema computacional bem denido; problema esse que dene a rela c ao I/O pretendida. Em geral diz-se que um determinado input constitui uma inst ancia do problema resolvido pelo algoritmo.

Import ancia dos Algoritmos


Areas t picas onde s ao utilizados algoritmos:
Internet: routing, searching, etc Criptograa Investiga c ao Operacional programas com mapas e.g. trajectos Matem atica ...

Exemplos de problemas complicados:


dado um mapa em que est ao assinaladas as dist ancias entre diversos pontos, encontrar o trajecto de menor dist ancia entre cada par de pontos. dado um conjunto de matrizes, possivelmente n ao quadradas e de diferentes dimens oes, encontrar a forma mais eciente de calcular o seu produto.

Import ancia dos Algoritmos (cont.)


Na procura de um algoritmo que resolva um determinado problema, interessa em geral encontrar um que seja eciente. H a, no entanto, problemas para os quais n ao se conhece uma solu c ao eciente. Esta classe de problemas denomina-se por NP. Os problemas NP-completos, uma subclasse dos anteriores, s ao especialmente interessantes porque:
aparentemente s ao simples n ao se sabe se existe um algoritmo eciente que os resolva aplicam-se a areas muito importantes se um deles for resol uvel de forma eciente, todos os outros o ser ao por vezes, ao resolver um problema NP-completo, contentamo-nos em encontrar uma solu c ao que aproxime a solu c ao ideal, em tempo u til.

Import ancia dos Algoritmos (cont.)


Por que raz ao e importante saber conceber e analisar algoritmos? Apesar de haver j a um grande n umero de problemas para os quais se conhecem algoritmos ecientes, nem todos est ao ainda resolvidos e documentados. Importa saber conceber novos algoritmos. Se a mem oria fosse gratuita e a velocidade ilimitada, qualquer solu c ao correcta seria igualmente v alida. Mas no mundo real, a eci encia de um algoritmo e determinante: a utiliza c ao de recursos assume grande import ancia. Algoritmos para um mesmo problema podem variar grandemente em termos de eci encia: podem ser diferen cas muito mais importantes do que as devidas ao hardware ou ao sistema operativo. Os Algoritmos s ao uma tecnologia que importa pois dominar, uma vez que as escolhas efectuadas a este n vel na concep c ao de um sistema podem vir a determinar a sua validade.
8

Introdu c ao ` a An alise de Algoritmos


Estudo de diferentes caracter sticas que permitem classicar e comparar os algoritmos A correc c ao de um algoritmo e fundamental. A an alise da correc c ao de algoritmos ser a a primeira que abordaremos. Os recursos necess arios ` a execu c ao de um algoritmo:
mem oria largura de banda hardware e particularmente: tempo de computa c ao

permitem comparar os algoritmos quanto ` a sua eci encia. A estrat egia que um algoritmo adopta para desempenhar uma determinada tarefa ou resolver um determinado problema e tamb em muito importante.
9

I. Introdu c ao ` a An alise de Correc c ao de Algoritmos


T opicos: Asser c oes e especica c ao do comportamento de algoritmos. Pr e-condi c oes e p os-condi c oes. Triplos de Hoare. L ogica de Hoare. Provas de correc c ao e gera c ao de condi c oes de verica c ao. Invariantes de ciclo. Provas de correc c ao envolvendo ciclos. Correc c ao parcial vs. correc c ao total. Variantes de ciclo. Casos de estudo: pesquisa em vectores.

10

Correc c ao de um Algoritmo
Um algoritmo diz-se correcto se para todos os valores dos inputs (vari aveis de entrada) ele p ara com os valores correctos dos outputs (vari aveis de sa da). Neste caso diz-se que ele resolve o problema computacional em quest ao. Nem sempre a incorrec c ao e um motivo para a inutilidade de um algoritmo: Em certas aplica co es basta que um algoritmo funcione correctamente para alguns dos seus inputs. Em problemas muito dif ceis, poder a ser suciente obter solu c oes aproximadas para o problema. A an alise da correc c ao de um algoritmo pretende determinar se ele e correcto, e em que condi c oes. Esta an alise pode ser efectuada com um elevado grau de formalismo recorrendo a uma l ogica de programas, baseada em provas indutivas utilizando invariantes de ciclo. Pode tamb em ser conduzida de modo semi-formal.
11

An alise de Correc c ao
A demonstra c ao da correc c ao de um algoritmo cuja estrutura n ao apresente ciclos pode ser efectuada por simples inspec c ao. Exemplo: int soma(int a, int b) { int sum; sum = a+b; return sum; } No caso de algoritmos recursivos, a prova adv em da deni c ao da solu c ao. Exemplo: int factorial(int n) { int f; if (n<1) f = 1; else f = n*factorial(n-1); return f; }
12

An alise de Correc c ao Pr e-condi c oes e p os-condi c oes


A an alise de correc c ao dos algoritmos baseia-se na utiliza c ao de asser c oes : proposi c oes l ogicas sobre o estado actual do programa (o conjunto das suas vari aveis). Por exemplo, x>0 a[i] < a[j ] i. 0 i < n a[i] < 1000 Pr e-condi c ao Uma propriedade que se assume como verdadeira no estado inicial de execu c ao do programa, i.e., s o interessa considerar as execu c oes do programa que satisfa cam esta condi c ao. P os-condi c ao Uma propriedade que se deseja provar verdadeira no estado nal de execu c ao do programa.
13

An alise de Correc c ao Triplos de Hoare

{P } C {Q} P e uma pr e-condi c ao C e o programa cuja correc c ao se considera Q e uma p os-condi c ao O triplo {P } C {Q} e v alido quando todas as execu c oes de C partindo de estados iniciais que satisfa cam P , caso terminem, resultem num estado nal do programa que satisfaz Q. Utilizaremos um sistema formal conhecido como L ogica de Hoare para raciocinar sobre a correc c ao de programas.
14

An alise de Correc c ao L ogica de Hoare

{Q[x e]} x = e {Q}

{P } C1 {R}

{R} C2 {Q}

{P } C1; C2 {Q}

{P b} Ct {Q}

{P b} Cf {Q}

{P } if (b) Ct else Cf {Q}

15

An alise de Correc c ao L ogica de Hoare


Regras de Consequ encia:

{P } C {Q} {P } C {Q}

se |= P P

{P } C {Q} {P } C {Q }

se |= Q Q

16

An alise de Correc c ao Exemplo 1

{x = x0 y = y0} swap {y = x0 x = y0} Considerando uma implementa c ao concreta de swap:

{x = x0 y = y0 } t = x; x = y; y = t; {y = x0 x = y0}

17

An alise de Correc c ao Exemplo 1

{x = x0 y = y0} |= x = x0 y = y0 x = x0 y = y0 {x = x0 y = y0} t = x; {t = x0 y = y0} x = y; { t = x 0 x = y0 } y = t; {y = x0 x = y0} Propagamos a p os-condi c ao para tr as, at e que atingimos a pr e-condi c ao. Neste ponto utilizamos uma regra de consequ encia para garantir que a pr e-condi c ao e mais forte do que a condi c ao propagada (neste caso e equivalente, mas n ao e sempre assim: a pr e-condi c ao podia ser por exemplo x = x0 y = y0 x > 0).

18

An alise de Correc c ao Exemplo 2

{x = x0 y = y0} sort2 {x y ((x = x0 y = y0) (y = x0 x = y0))} Considerando uma implementa c ao concreta de sort2: {x = x0 y = y0 } if (x > y ) { t = x; x = y ; y = t } else { } {x y ((x = x0 y = y0) (y = x0 x = y0))} Propagaremos agora a p os-condi c ao ao longo dos dois ramos do condicional, o que dar a origem a duas utiliza c oes da regra de consequ encia.
19

An alise de Correc c ao Exemplo 2


{x = x0 y = y0} if (x > y ) { |= x = x0 y = y0 x > y y x (y = x0 x = y0) (x = x0 y = y0) {y x (y = x0 x = y0) (x = x0 y = y0)} t = x; {y t (y = x0 t = y0) (t = x0 y = y0)} x = y; {x t (x = x0 t = y0) (t = x0 x = y0)} y = t; } else { |= x = x0 y = y0 (x > y ) x y ((x = x0 y = y0) (y = x0 x = y0)) {x y ((x = x0 y = y0) (y = x0 x = y0))} } {x y ((x = x0 y = y0) (y = x0 x = y0))}
20

An alise de Correc c ao Invariantes de Ciclo


No caso de algoritmos que incluam ciclos, uma prova de correc c ao implica uma an alise da evolu c ao de cada ciclo, em todas as suas itera c oes. Identicamos para isso um invariante de ciclo uma propriedade que se mant em verdadeira durante toda a execu c ao do ciclo, e que reecte todas as transforma c oes do estado que esse ciclo efectua durante a sua execu c ao. Para utilizar um invariante I numa prova de correc c ao temos de demonstrar o seguinte. Queremos mostrar a validade do triplo {P } while (b) C {Q}: Inicializa c ao O invariante e satisfeito antes da primeira itera c ao: |= P I Preserva c ao Se o invariante e satisfeito no in cio de uma itera c ao, ent ao e-o tamb em no in cio da itera c ao seguinte o triplo {I b} C {I } e v alido. Utilidade Se a execu c ao do ciclo parar, o invariante e sucientemente forte para garantir a satisfa c ao da p os-condi c ao: |= I b Q
21

An alise de Correc c ao L ogica de Hoare

{I b} C {I } {I } while (b) C {I b} A utiliza c ao desta regra para provar a correc c ao de um triplo {P } while (b) C {Q} com uma pr e-condi c ao P e uma p os-condi c ao Q arbitr arias, d a origem ` as seguintes condi c oes de verica c ao: Preserva c ao do invariante: as CVs da prova de correc c ao de {I b} C {I } Inicializa c ao do invariante: |= P I (regra de consequ encia) Utilidade do invariante: |= I b Q (regra de consequ encia).
22

Invariantes de Ciclo Exemplo 1


Problema Pesquisa (ineciente!) da u ltima ocorr encia do valor k num vector. int procura(int vector[], int a, int b, int k) { int i, f; f = -1; for (i=a; i<=b; i++) if (vector[i]==k) f = i; return f; } Pr e-condi c ao a b . P os-condi c ao A vari avel f cont em o valor -1 caso k n ao ocorra nas posi c oes [a . . . b] do vector. Caso contr ario, o valor de f ser a o maior no intervalo [a . . . b] tal que vector [f ] = k .

23

Invariantes de Ciclo Exemplo 1 (cont.)


Invariante No in cio de cada itera c ao, a i b + 1, e a vari avel f ter a o valor -1 caso o valor k n ao ocorra nas posi c oes [a . . . (i 1)] do vector. Caso contr ario, f ter a o maior valor no intervalo [a . . . i 1] tal que vector [f ] = k . Inicializa c ao
Antes da primeira itera c ao i = a e f = 1. O valor k n ao pode existir nas posi c oes [a . . . (a 1)] do vector: o invariante e verdadeiro.

Utilidade
No nal da execu c ao do ciclo, i = b + 1. Como o invariante se mant em v alido ao longo de toda a execu c ao do ciclo, ent ao: se o valor k existe entre as posi c oes [a..b] do vector, ent ao f ter a o valor da u ltima posi c ao onde foi encontrado; caso contr ario, f ter a o valor -1.

24

Invariantes de Ciclo Exemplo 1 (cont.)


Preserva c ao
Assume-se que o invariante e v alido no in cio da itera c ao i. Se o valor k n ao estiver na posi c ao i do array, o valor de f n ao ser a alterado. No in cio da itera c ao i + 1 a validade do invariante mant em-se tamb em inalterada. Se o valor k estiver na posi c ao i do vector, o valor de f ser a alterado para i. No in cio da itera c ao i + 1 o invariante e satisfeito: f ter a o valor da u ltima posi c ao onde k foi encontrado.

Isto corresponde ` a prova de validade do triplo de Hoare {I b} C {I }. Exerc cio: Reescrever esta prova em estilo formal, come cando por escrever o invariante em linguagem matem atica.

25

Invariantes de Ciclo Exemplo 1 (cont.)


Para a prova em l ogica de Hoare recorremos a um programa equivalente: f = -1; i = a; while (i<=b) { if (vector[i]==k) f = i else {} ; i++; } Invariante I aib+1 (k vector [a . . . (i 1)] f = 1) (k vector [a . . . (i 1)] (f {a . . . i 1} vector [f ] = k (j {a . . . i 1}. vector [j ] = k f j )))

26

Invariantes de Ciclo Exemplo 1 (cont.)

Pr e-condi c ao P P os-condi c ao Q (k vector [a . . . b] f = 1) (k vector [a . . . b] (f {a . . . b} vector [f ] = k (j {a . . . b}. vector [j ] = k f j ))) ab

Note-se que k vector [a . . . b] j {a . . . b}. vector [j ] = k


27

Invariantes de Ciclo Exemplo 1 (cont.)


// { P } // VC1: P -> I [i -> a][f -> -1] // { I [i -> a][f -> -1] } f = -1; // { I [i -> a] } i = a; // { I } while (i<=b) { // { I /\ i<=b} CORPO // { I } } // { I /\ ~(i<=b) } // VC2: I /\ ~(i<=b) -> Q // { Q }
28

Invariantes de Ciclo Exemplo 1 (cont.)

// { I /\ i <= b } if (vector[i]==k) // VC3: I /\ i <= b /\ vector[i]==k -> I [i -> i+1][f -> i] // { I [i -> i+1][f -> i] } f = i else // VC4 : I /\ i <= b /\ ~(vector[i]==k) -> I [i -> i+1] // { I [i -> i+1] } {} // { I [i -> i+1] } i++; // { I }

29

Invariantes de Ciclo Exemplo 2


Problema Pesquisa da primeira ocorr encia do valor k num vector. Vers ao ineciente: int procura(int vector[], int a, int b, int k) { int i, f; i = a; f = -1; while (i<=b) { if ((f==-1) && (vector[i]==k)) f = i; i++; } return f; } Invariante No in cio de cada itera c ao, a i b + 1, e se o valor de f for -1 ent ao k n ao ocorre nas posi c oes [a . . . i 1] do vector; caso contr ario, k ocorre na posi c ao f e n ao ocorre nas posi c oes [a . . . f 1].
30

Invariantes de Ciclo Exemplo 2 (cont.)


Inicializa c ao trivial . . . Preserva c ao Se no in cio da itera c ao i o valor de f for -1 podemos assumir que k n ao ocorre nas posi c oes [a . . . i 1], e: se vector[i] contiver o valor k, ent ao ser a executado f = i, e no in cio da pr oxima itera cao, com i = i + 1, tem-se que k ocorre na posi c ao f , e k n ao ocorre nas posi c oes [a . . . f 1], uma vez que f = i. Cao contr ario, no in cio da pr oxima itera cao, com i = i + 1, tem-se que f tem ainda valor -1, e k n ao ocorre nas posi c oes [a . . . i 1]. Se no in cio da itera c ao i o valor de f for outro, ent ao nesta itera c ao apenas i ser a actualizado, e no in cio da pr oxima itera cao, com i = i + 1, f ter a ainda o mesmo valor, pelo que o invariante e preservado. Utilidade O ciclo termina sempre com i = b + 1. Se o valor de f for -1 ent ao k n ao ocorre nas posi c oes [a . . . b] do vector; caso contr ario, k ocorre na posi c ao f e n ao em posi c oes inferiores: f corresponde ` a primeira ocorr encia.

31

Invariantes de Ciclo Exemplo 3


Problema Pesquisa da primeira ocorr encia do valor k num vector. int procura(int vector[], int a, int b, int k) { int i; i = a; while ((i<=b) && (vector[i]!=k)) i++; if (i>b) return -1; else return i; } Invariante a i b + 1 e k n ao se encontra nas posi c oes [a . . . i 1] do vector. Utilidade O ciclo termina com i = b + 1, ou ent ao com vector [i] = k . No primeiro caso, o invariante implica que k n ao se encontra nas posi c oes [a . . . b] do vector; no segundo, que n ao se encontra nas posi c oes [a . . . i 1], e vector [i] = k . Exerc cio Terminar a demonstra c ao de correc c ao do algoritmo.
32

Invariantes de Ciclo Exemplo 4


Problema Pesquisa bin aria de uma ocorr encia de k num vector ordenado. int procura(int vector[], int a, int b, int k) { int p; if (a>b) return -1 do { p = (a+b)/2; if (vector[p]>=k) b = p; else a = p; } while (a<b); if (vector[a]==k) return a; else return -1; } Exerc cios Escrever o invariante de ciclo e demonstrar a correc c ao do algoritmo. Optimizar algoritmo por forma a parar mais cedo quando vector[p]==k e provar correc c ao da nova vers ao.
33

An alise de Correc c ao Correc c ao Total


A no c ao de correc c ao que temos considerado e parcial a validade do triplo {P } C {Q} requer que Q seja satisfeito no estado nal do programa, caso a execu c ao deste termine. Pode-se considerar uma no c ao de correc c ao mais forte, que exija a termina c ao do programa. Usaremos uma nota c ao diferente para os triplos de Hoare correspondentes: o triplo [P ] C [Q] e v alido se e s o se todas as execu c oes de C partindo de estados iniciais que satisfa cam P terminam, e resultam num estado nal que satisfaz Q. Num programa imperativo, as constru c oes capazes de introduzir n aotermina c ao s ao os ciclos e a recursividade. Veremos apenas como estudar a termina c ao dos primeiros, recorrendo ` a no c ao de variante de ciclo.

34

An alise de Correc c ao Variantes de Ciclo


Um variante de ciclo e uma express ao inteira n ao-negativa, constru da a partir das vari aveis do programa, e cujo valor decresce estritamente com a execu c ao de cada itera c ao. int procura(int vector[], int a, int b, int k) { int i, f; f = -1; for (i=a; i<=b; i++) if (vector[i]==k) f = i; return f; } Variante v = b i Note-se que v e n ao-negativo quando s ao executadas itera c oes: |= i b v 0 Por outro lado, o valor de v decresce estritamente em cada itera c ao, uma vez que i = i + 1 e b = b, logo v = b i = b (i + 1) = v 1 < v .
35

An alise de Correc c ao L. de Hoare para Correc c ao Total


[I b v = v0] C [I v < v0] [I ] while (b) C [I b]

|= I b v 0

A utiliza c ao desta regra para provar a correc c ao de um triplo [P ] while (b) C [Q] d a origem ` as seguintes condi c oes de verica c ao: Inicializa c ao do variante: |= I b v 0 Preserva c ao do invariante e decr escimo do variante: as CVs da prova de correc c ao de [I b v = v0] C [I v < v0] Inicializa c ao do invariante: |= P I (regra de consequ encia) Utilidade do invariante: |= I b Q (regra de consequ encia).
36

Variantes de Ciclo Exemplo 1

// { P } // VC1: P -> I [i -> a][f -> -1] // { I [i -> a][f -> -1] } f = -1; // { I [i -> a] } i = a; // { I } while (i<=b) { // VC0: I /\ i <= b -> b-i >= 0 // { I /\ i<=b} CORPO // { I } } // { I /\ ~(i<=b) } // VC2: I /\ ~(i<=b) -> Q // { Q }
37

Variantes de Ciclo Exemplo 1 (cont.)


// { I /\ i <= b /\ b-i = V0} if (vector[i]==k) // VC3: I /\ i <= b /\ b-i = V0 /\ vector[i]==k // -> (I /\ b-i < V0) [i -> i+1][f -> i] // { I [i -> i+1][f -> i] } f = i else // VC4 : I /\ i <= b /\ b-i = V0 /\ ~(vector[i]==k) // -> (I /\ b-i < V0) [i -> i+1] // { (I /\ b-i < V0) [i -> i+1] } {} // { (I /\ b-i < V0) [i -> i+1] } i++; // { I /\ b-i < V0 }

38