AMC T3

Propaganda
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.
Algoritmo da 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;
}
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.
*/
Algoritmo da 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 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 &
# n−1 &
#1
&
O %% ∑∑1(( = O % ∑ i ( = O % n(n −1)( = O(n 2 )
$2
'
$ i=1 '
$ i=1 j=0 '
Análise do melhor caso:
BTime(insertionSort(V,n)=
# n−1 &
O % ∑1( = O ( n −1) = O(n)
$ i=1 '
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
i
=
2
j=0
j=0 i +1
-  ATime(insertionsort(V,n))=
∑ j × p( j) = ∑
# n−1 i &
# n−1 i &
#1
&
O % ∑ ( = O % ∑ ( = O % n(n −1)( = O(n 2 )
$4
'
$ i=1 2 '
$ i=1 2 '
Algoritmo Bubblesort
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
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;
/* 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];
Pior, melhor e caso médio?
V[j]=V[j+1];
O(n^2)
V[j+1]=aux;
}
j--;
}
i++;
}
}
return;
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
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
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?
Download