Análise de programas imperativos AMC 2011/12 ì Paulo Mateus Departamento de Matemática IST 2012
Objectivos ì Noção de invariante e variante de um ciclo ì Prova (informal) da correção de algoritmos imperativos ì Algoritmos de ordenação ì Análise da complexidade dos algoritmos de ordenação ì Análise do pior caso ì Análise de caso médio suposições probabilísticas
Invariante ì Invariante na Lógica de Hoare: ì Def (informal): Uma asserção I diz-se um invariante para um ciclo while(g){ corpo se, quando for verificada no início do ciclo, também é verificada no fim de cada iterada do ciclo. ì ì Para tornar esta definição rigorosa era necessário definir: ì Estado do programa (valores das variáveis + estado do controlo) ì Sintaxe da lógica para os invariantes (primeira-ordem com predicados relevantes) ì Semântica Nesta disciplina opta-se, como é comum na literatura, por utilizar linguagem matemática informal para analisar os algoritmos imperativos.
Invariante - factorial #include <stdio.h> /* Exemplo: factorial com contador a decrescer*/ int main() { int i, r, n; scanf( %d,&n); r=1; i=n; n /* Invariante r = k i >=1 */ k=i while(i>=2) { r=r*i; i--; printf( O factorial de %d é %d.\n, n, r); return 0; Prop: O programa Exemplo2, se terminar, calcula o factorial.
void insertionsort(int V[], int n) { int i=1, j, aux; while(i < n){ aux=v[i]; j = i-1; while(j>=0 && V[j] >aux) { V[j+1] = V[j]; j--; V[j + 1] = aux; i++; return; Algoritmo da Inserção
Invariante - Inserção void insertionsort(int V[], int n) { int i=1, j, aux; /* Invariante 1: Os valores V[0]...V[i-1] estão ordenados e i<=n */ while(i < n){ aux=v[i]; j = i-1; /* Invariante 2: Os valores V[j+1],..,V[i]>= aux e j>=-1*/ while(j>=0 && V[j] >aux) { V[j+1] = V[j]; j--; V[j + 1] = aux; i++; return; Prop: A função insertionsort ordena por ordem crescente o vector V.
Variante ì Def. Uma relação (A,<) é bem fundada se qualquer subconjunto não vazio B de A tem elemento minimal. ì Def. Um variante de um ciclo while(g){c e invariante I é um mapa dos estados que satisfazem I para o suporte A de uma relação bem fundada (A,<) cujo valor decresce estritamente em relação a < por cada iterada do ciclo.
Variante ì Regra da correção total do cálculo de Hoare Teo: Dado um invariante I, um ciclo while termina sse existe um variante para esse ciclo e I. Def: Um variante diz-se natural se o suporte da relação bemfundada for um subconjunto dos números naturais. Teo: Ciclos while com variantes naturais não são universais no que diz respeito a algoritmos computáveis à Turing.
Variante- factorial #include <stdio.h> /* Exemplo: factorial com contador decrescente*/ int main() { int i, r, n; scanf( %d,&n); r=1; i=n; /* Variante ({1...n,<) e f: {σ:σ[i]<=nè {1...n tq f(σ)=σ[i] */ while(i>=2) { r=r*i; i--; printf( O factorial de %d é %d.\n, n, r); return 0; Prop: O programa factorial termina para todo o input. Exer: Encontre variantes para os ciclos do insertionsort.
void insertionsort(int V[], int n) { int i=1, j, aux; while(i < n){ aux=v[i]; j = i-1; while(j>=0 && V[j] >aux) { V[j+1] = V[j]; j--; V[j + 1] = aux; i++; return; Algoritmo da Inserção
Análise no pior caso - inserção void insertionsort(int V[], int n) { int i=1, j, aux; while(i < n){ aux=v[i]; j = i-1; while(j>=0 && V[j] >aux) { V[j+1] = V[j]; j--; V[j + 1] = aux; i++; return; Análise do pior caso: Time(insertionSort(V,n)= # n 1 i 1 & O % 1 ( = O # n 1 i & # % ( = O 1 & % n(n 1) ( = O(n 2 ) $ i=1 j=0 ' $ i=1 ' $ 2 ' Análise do melhor caso: BTime(insertionSort(V,n)= # n 1 & O% 1( = O n 1 $ ' i=1 ( ) = O(n)
Análise no caso médio - inserção ì Para proceder a análise do caso médio é necessário fazer suposições probabilísticas sobre a entrada de dados. ì Diferentes suposições probabilísticas podem levar a diferentes comportamentos médios. ì A análise corresponde a calcular o valor esperado da complexidade temporal tendo em linha de conta a distribuição de probabilidades das entradas
Análise no caso médio - inserção void insertionsort(int V[], int n) { int i=1, j, aux; while(i < n){ aux=v[i]; j = i-1; while(j>=0 && V[j] >aux) { V[j+1] = V[j]; j--; V[j + 1] = aux; i++; return; Análise do caso médio: - Assume que no segundo ciclo poderá terminar com j=-1,0,.,i-1 equiprovavelmente. - O segundo ciclo é iterado i i j j p( j) = = i j=0 j=0 i +1 2 - ATime(insertionsort(V,n))= # O% $ n 1 i=1 i & # ( = O% 2 ' $ n 1 i=1 i & # ( = O 1 & % n(n 1) ( = O(n 2 ) 2 ' $ 4 '
void BubbleSort(int V[], int n) { int i=1, j, aux; while(i < n){ j = 0; while(j<n-i) { if(v[j+1] < V[j]) { aux=v[j]; V[j]=V[j+1]; V[j+1]=aux; ; j++; i++; return; Algoritmo Bubblesort
Algoritmo Bubblesort void BubbleSort(int V[], int n){ int i=1, j, aux; /* I1: V[n-i+1]...V[n-1] está ordenado e tem os maiores elementos de V e i<=n+1 */ while(i <= n){ j = 0; /* I2: V[j]é o maior valor de V[0]...V[j] de V e j<=n-i*/ while(j<n-i) { if(v[j+1] < V[j]) { aux=v[j]; V[j]=V[j+1]; V[j+1]=aux; j--; i++; return;
Algoritmo Bubblesort void BubbleSort(int V[], int n){ int i=1, j, aux; /* I1: V[n-i+1]...V[n-1] está ordenado e tem os maiores elementos de V e i<=n+1 */ while(i <= n){ j = 0; i++; return; /* I2: V[j]é o maior valor de V[0]...V[j] de V e j<=n-i*/ while(j<n-i) { if(v[j+1] < V[j]) { j--; aux=v[j]; V[j]=V[j+1]; V[j+1]=aux; Pior, melhor e caso médio? O(n^2)
Algoritmo QuickSort void quicksort(int vec[], int left, int right) { int r; if (right > left) { r = partition(vec, left, right); /* pivot */ quicksort(vec, left, r - 1); quicksort(vec, r + 1, right);
int partition(int vec[], int left, int right) { int i, j; i = left; j = left + 1; while( j <= right) { if (vec[j] < vec[left]) { ++i; swap(vec,i,j); j++; swap(vec,left, i); return i; Algoritmo QuickSort
void swap(int vec[] a, b) { int tmp; tmp = vec[a]; vec[a] = vec[b]; vec[b] = tmp; Algoritmo QuickSort
Algoritmo QuickSort void quicksort(int vec[], int left, int right) { int r; if (right > left) { r = partition(vec, left, right); /* pivot */ quicksort(vec, left, r - 1); quicksort(vec, r + 1, right);
Algoritmo QuickSort Correção por indução! Análise de complexidade por resolução de recurrências?