Sunteți pe pagina 1din 66

Sistemas de Informação

Computabilidade e
Complexidade
(COM10014)

Profa. Juliana Pinheiro Campos


E-mail: jupcampos@gmail.com
TEORIA DA COMPUTAÇÃO

Complexidade de algoritmos

A área da computação que estuda/ analisa a


eficiência dos algoritmos é chamada análise de
algoritmos.
A complexidade de um algoritmo é o custo
associado à execução desse algoritmo
(quantidade de recursos necessários para sua
execução).
Os recursos tempo de execução e espaço
ocupado são muito importantes. Nessa disciplina
estudaremos a complexidade de tempo.
TEORIA DA COMPUTAÇÃO

Complexidade de algoritmos

 Em muitas situações podem existir vários algoritmos


para resolver o mesmo problema, sendo necessário
escolher aquele que é o melhor.
 Para escolher o melhor algoritmo para resolver um
problema é necessário ter 1 forma de comparar
algoritmos (uma medida de custo) que resolvam o
mesmo problema.
 Quando conseguimos determinar o menor custo
possível para resolver problemas temos a medida
da dificuldade inerente para resolver tais problemas.
TEORIA DA COMPUTAÇÃO

Complexidade de algoritmos

 Quando o custo de um algoritmo é igual ao menor


custo possível, dizemos que o algoritmo é ótimo
para a medida considerada.
 Porque é importante estudar a complexidade de
algoritmos?
• Para conhecer os limites da computação.
Mesmo quando um problema é decidível, ele
pode não ser solúvel na prática se a solução
requer uma quantidade excessiva de tempo ou
memória.
TEORIA DA COMPUTAÇÃO

Complexidade de algoritmos

 Como medir o custo/eficiência de um algoritmo?


• Executar o programa em um computador real.
Desvantagens:resultados dependem de
hardware, é necessário implementar e rodar o
algoritmo, etc.
• Uso de um modelo matemático baseado em um
computador idealizado. O conjunto de
operações a serem executadas deve ser
especificado, assim como o custo associado à
execução de cada operação. É usual considerar
apenas o custo de operações relevantes.
TEORIA DA COMPUTAÇÃO

Complexidade de algoritmos

Para medir o custo de execução de um algoritmo


é comum definir uma função de custo.
Função de complexidade (função de custo):
f(n) é a medida de tempo necessário (em função
do nº de operações executadas) para executar
um algoritmo para um problema de tamanho n.
A complexidade de tempo não representa tempo
diretamente, mas o nº de vezes que
determinada operação considerada relevante é
executada.
TEORIA DA COMPUTAÇÃO

Complexidade de algoritmos

Ex: algoritmo para encontrar o maior elemento de


um vetor de inteiros de tamanho n.
int max(int* vetor){
int i, temp; Seja f uma função de
temp = vetor[0]; complexidade tal que f(n)
for(i = 1; i <= n; i++){ é o número de comparações
entre os elementos do vetor.
if(vetor[i] > temp) Se o vetor contém n
temp = vetor[i]; elementos, f(n) = n-1.
}
return temp;
}
TEORIA DA COMPUTAÇÃO

Complexidade de algoritmos

A medida do custo de execução de um algoritmo


depende principalmente do tamanho da entrada
de dados. Por isso, é comum considerar o tempo
de execução de um programa como uma função
do tamanho da entrada.

Para alguns algoritmos, o custo de execução é


uma função da entrada particular dos dados, não
apenas do tamanho da entrada.
TEORIA DA COMPUTAÇÃO

Complexidade de algoritmos

Quando o custo de execução não depende


apenas do tamanho da entrada, temos que
distinguir 3 cenários:
• Melhor caso: considera o menor tempo de
execução sobre todas as possíveis entradas (tempo
+ curto).
• Caso médio: Considera a média dos tempos de
execução para todas as entradas de um
comprimento específico.
• Pior caso: considera o maior tempo de execução
sobre todas as possíveis entradas (tempo + longo).
TEORIA DA COMPUTAÇÃO

Complexidade de algoritmos

Ex: algoritmo que busca o elemento x em um


vetor de inteiros de tamanho n.

bool busca(int * vetor, int n, int x){


int i = 0;
while(vetor[i] != x && i < n){
i++;
}
if(vetor[i] == x)
return true;
else
return false;
}
TEORIA DA COMPUTAÇÃO

Complexidade de algoritmos

 Seja f(n) a função de complexidade que é o número


de comparações de x com os elementos do vetor.
 O nº de comparações vai depender da posição do
vetor onde está o elemento x procurado:
• Melhor caso: x é o 1º elemento do vetor. Nesse
caso, f(n) = 1.
• Caso médio: x está no meio da lista. f(n) = n/2
pois serão necessárias necessárias
aproximadamente n/2 comparações.
• Pior caso: x é o último elemento do vetor, ou não
está no vetor. Assim, f(n) = n.
TEORIA DA COMPUTAÇÃO

Análise assintótica

A análise assintótica é uma forma de estimar o


tempo de execução de um algoritmo (pois o
tempo exato é frequentemente uma expressão
complexa) quando ele é executado sobre
entradas grandes.
É um método para descrever o comportamento de
limites.
Existe uma relação direta entre o tempo de
resposta de um algoritmo e o tamanho da entrada
n fornecida para o algoritmo.
TEORIA DA COMPUTAÇÃO

Análise assintótica

Quando o valor de n é pequeno, qualquer


algoritmo custa pouco para ser executado.
Para a análise de algoritmos, considera-se o
comportamento de suas funções de complexidade
para valores grandes de n, isto é, estuda-se o
comportamento assintótico das funções de custo.
O comportamento assintótico de f(n) representa o
limite do comportamento do custo quando n
cresce.
TEORIA DA COMPUTAÇÃO

Notação O (O-grande ou Big O)

Sejam 2 funções f(n) e g(n), dizemos que f(n) é O


(g(n)) se existem inteiros positivos c e m tais que:

f(n) ≤ c g(n), para todo n ≥ m

Dizemos que f(n) é da ordem no máximo g(n).


Também podemos dizer que g(n) é um limite
superior para a taxa de crescimento de f(n).
TEORIA DA COMPUTAÇÃO

Notação O (O-grande ou Big O)

m
TEORIA DA COMPUTAÇÃO

Notação O (O-grande ou Big O)

Propriedades:
• f(n) = O(f(n))
• c x O(f(n)) = O(f(n)) , onde c = constante
• O(f(n)) + O(f(n)) = O(f(n))
• O(O(f(n))) = O(f(n))
• O(f(n)) + O(g(n)) = O(max(f(n), g(n)))
• O(f(n))O(g(n)) = O(f(n)g(n))
• f(n)O(g(n)) = O(f(n)g(n))
TEORIA DA COMPUTAÇÃO

Notação Ω (Ω-grande)

Sejam 2 funções f(n) e g(n), dizemos que f(n) é Ω


(g(n)) se existem inteiros positivos c e m tais que:

f(n) ≥ c g(n), para n ≥ m

Em outras palavras, f(n) é Ω (g(n)) se g(n) é O


(f(n)).
Dizemos que g(n) é um limite inferior para a taxa
de crescimento de f(n).
TEORIA DA COMPUTAÇÃO

Notação Θ (theta)

Sejam 2 funções f(n) e g(n), dizemos que f(n) é


Θ(g(n)) se existem inteiros positivos c1, c2 e m
tais que:
c1g(n) ≤ f(n) ≤ c2g(n), para todo n ≥ m

Em outras palavras, f(n) é Θ(g(n)) se f(n) é O


(g(n)) e Ω (g(n)) ao mesmo tempo.
Exprime o fato de que duas funções possuem a
mesma ordem de grandeza assintótica.
TEORIA DA COMPUTAÇÃO

Classes de comportamento assintótico

Se f(n) é uma função de complexidade para um


algoritmo F, então O(f(n)) é considerada a
complexidade assintótica ou comportamento
assintótico do algoritmo F.

O(f(n)) é a ordem de grandeza de um algoritmo


(comportamento no pior caso).
Se f(n) = cknk + ck-1nk-1 + ... + c1n + c0, dizemos que
f(n) é O(nk).
TEORIA DA COMPUTAÇÃO

Classes de comportamento assintótico

Imaginamos que o aumento da entrada deve


aumentar o nº de operações realizadas na
mesma proporção ou numa proporção linear.
Muitos algoritmos se enquadram nesse
comportamento, mas existem outros tipos de
comportamento.
Os algoritmos podem ser classificados pelo tipo
de função matemática que define seu
comportamento.
TEORIA DA COMPUTAÇÃO

Classes de comportamento assintótico

 Em geral, a complexidade de um algoritmo se


enquadra em uma das seguintes classes:
• f(n) = O(1): complexidade constante. As instruções são
executadas um número fixo de vezes, independente do
tamanho de n.
• f(n) = O(log(n)): complexidade logarítmica. Ocorre
tipicamente em algoritmos que resolvem um problema
transformando-o em problemas menores.
• f(n) = O(n): complexidade linear. Ocorre tipicamente em
algoritmos que realizam um pequeno trabalho sobre cada
elemento da entrada.
TEORIA DA COMPUTAÇÃO

Classes de comportamento assintótico

• f(n) = O(n log n): complexidade logaritmo-linear. Ocorre


tipicamente em algoritmos que resolvem um problema
quebrando-o em problemas menores, resolvendo cada um
deles independentemente e depois juntando as soluções.
• f(n) = O(n2): complexidade quadrática. Ocorre quando os
itens de dados são processados aos pares, muitas vezes
em um laço dentro do outro.
• f(n) = O(n³): complexidade cúbica. São úteis apenas para
resolver pequenos problemas.
• f(n) = O(cn) onde c é uma constante: complexidade
exponencial. Eles ocorrem na solução de problemas
quando se usa força bruta para resolvê-los. Quando n
dobra, o tempo fica elevado ao quadrado.
TEORIA DA COMPUTAÇÃO

Classes de comportamento assintótico

• f(n) = O(n!): complexidade fatorial. Tem comportamento


muito pior que algoritmos de complexidade exponencial.
Também ocorrem na solução de problemas quando se usa
força bruta para resolvê-los.

 Ao elaborarmos um algoritmo para resolver alguma tarefa,


procuramos sempre implementar um algoritmo que tenha a
menor classe assintótica. Um algoritmo O (log n) com
entrada grande exige um nº de operações muito menor que
um algoritmo O (n2). Quando tais algoritmos resolvem o
mesmo problema, óbvio que preferimos utilizar o que é
O(log n).
TEORIA DA COMPUTAÇÃO

Classes de comportamento assintótico

 Um algoritmo cuja função de complexidade é O(p(n))


onde p(n) é um polinômio é chamado algoritmo de
complexidade polinomial.
 Algoritmos exponenciais são geralmente simples
variações de pesquisa exaustiva, enquanto algoritmos
polinomiais são geralmente obtidos mediante o
entendimento + profundo da estrutura do problema.
 Um problema é chamado de intratável se não há
algoritmo de complexidade polinomial para resolvê-lo.
E é chamado de tratável se há algoritmo de
complexidade polinomial para resolvê-lo.
TEORIA DA COMPUTAÇÃO

Princípios para realizar a análise de


algoritmos

 A determinação do tempo de execução de um programa


qualquer pode se tornar um problema matemático
complexo quando se deseja determinar o valor exato da
função de complexidade.
 Mas a determinação da ordem do tempo de execução de
um programa pode ser uma tarefa + simples.
 Isso é feito considerando apenas o termo de mais alta
ordem da expressão para o tempo de execução do
algoritmo, desconsiderando tanto o coeficiente daquele
termo quanto quaisquer termos de ordem + baixa.
TEORIA DA COMPUTAÇÃO

Princípios para realizar a análise de


algoritmos

 O tempo de execução de um comando de atribuição,


leitura ou escrita é constante, ou seja, O(1).
 O tempo de execução de uma sequencia de comandos é o
maior tempo de qualquer comando da sequencia.
 O tempo de execução de um comando de decisão é igual
ao tempo de execução dos comandos dentro da condição
mais o tempo de verificar a condição (que é O(1)).
 O tempo de execução de um laço é igual ao tempo de
execução do corpo do laço mais o tempo de avaliar a
condição de parada (que é O(1)) multiplicado pelo nº de
vezes que o laço é executado.
TEORIA DA COMPUTAÇÃO

Princípios para realizar a análise de


algoritmos
 Quando o programa chama funções não recursivas,
calcula-se o tempo de execução de cada uma e soma
esses custos. Equivale ao tempo de execução da maior.
 Para funções recursivas, associa a função de
complexidade (equações de recorrência) para cada uma e
calcula-se o custo.
 Obs.: Blocos que pertencem a comandos de decisão ou
repetição podem ou não ser executados.
 Obs.: O custo de um laço pode ser calculado por meio de
um somatório. Laços encadeados implicam somatórios de
somatórios. Resolvemos sempre do laço mais interno para
o mais externo.
TEORIA DA COMPUTAÇÃO

Propriedades importantes
 Somatórios
TEORIA DA COMPUTAÇÃO

Propriedades importantes
 Logaritmo
TEORIA DA COMPUTAÇÃO

Exemplos

 1) Função que conta quantos valores consecutivos


são idênticos
int consec(int* vetor, int n){
Qual o custo de execução
int s = 0; da linha marcada? Número
de vezes que o corpo do for
for(int i = 0; i <= n - 1 ; i++) será executado.
if(vetor[i] == vetor[i + 1]) i = n-1

∑ 1 = n = O(n)
s = s + 1; i= 0

return s;
}
TEORIA DA COMPUTAÇÃO

Exemplos

 2) Função que encontra o valor máximo em um vetor


int maior(int* vetor, int n){ Qual o custo de execução do
int m = vetor[0]; algoritmo ( custo total de
comandos executados)?
for(int i = 1; i < n ; i++)
f(n) = c1 + somatório(c2 + c3)
if(vetor[i] > m)
+ (t x c4) + c5
m = vetor[i];
Onde t é o nº de vezes que o
teste da linha 4 é executado e
return m; ci o custo de execução da
operação na linha i dentro da
} função.
Faça a análise do melhor e
pior caso.
TEORIA DA COMPUTAÇÃO

Recursão e relação de recorrência

 Relação de recorrência ou equação de recorrência é


uma maneira de definir uma função recursiva por uma
expressão representando a mesma função.
 A função de complexidade de algoritmos recursivos
é dada por uma relação de recorrência. A análise de
algoritmos recursivos envolve a solução de uma
equação de recorrência.
 Solução de forma fechada: solução para uma
relação de recorrência onde pode-se substituir o valor
de n e obter diretamente o seu resultado.
TEORIA DA COMPUTAÇÃO

Técnica para solucionar relação de


recorrência

 Expanda, suponha e verifique:


• Usa repetidamente a relação de recorrência para
expandir a expressão para o n-ésimo elemento
até que um padrão geral de comportamento possa
ser deduzido. Finalmente, a suposição é verificada
por indução matemática.
TEORIA DA COMPUTAÇÃO

Técnica para solucionar relação de


recorrência

 Ex: Seja a relação de recorrência abaixo


1. S(1) = 2
2. S(n) = 2 S(n-1) para n > = 2.

Expanda: S(n) = 2 S(n-1)


= 2 x 2 x S(n-2)
= 2 x 2 x 2 x S(n-3)
=…
TEORIA DA COMPUTAÇÃO

Técnica para solucionar relação de


recorrência
Suponha: Podemos supor que após k expansões
sucessivas, S(n) = 2k x S(n – k). Essa expansão vai
parar quando n – k = 1, ou seja, quando k = n-1. Assim:
S(n) = 2n-1 S (n – (n – 1)) = 2n-1 S (1) = 2n-1 x 2 = 2n

Verifique: Desejamos mostrar que S(n) = 2n


Caso Base: S(1) = 21 = 2; verdadeiro pela equação 1.
H.I.: Supomos que S(k) = 2k seja verdade.
Passo indutivo: S(k+1) = 2k+1. Pela definição de S(n)
temos S(k+1) = 2 x S(K+1-1) = 2 S(K) = 2 x 2k pela H.I.
= 2 k+1.
TEORIA DA COMPUTAÇÃO

Exemplos
1) void algoritmo(int n){
if(n > 1){
int p = 1;
for(int i = 2; i <=n; i++)
if(A[p] < A[i]){
p = i;
aux = A[p];
A[p] = A[n];
algoritmo(n-1);
}
}
}
TEORIA DA COMPUTAÇÃO

Exemplos
 Qual o custo de execução da linha marcada?
Seja T(n) a função que determina o nº de vezes que a
comparação na linha marcada é executada. Então:
T(1) = 0
T(n) = n-1 + T(n-1) para n > 1

Resolvendo a relação de recorrência acima


encontramos
T(n) = (n2-n)/2 = O(n2)
TEORIA DA COMPUTAÇÃO

Exemplos
2) int busca-binaria(int l, int r, int x){
if(l == r){
if(A[l] == x)
return l;
else
return 0;
}
else{
m = (l+r)/2;
if(x < A[m])
busca-binaria(l, m – 1, x);
else
busca-binaria(m, r, x);
}
}
TEORIA DA COMPUTAÇÃO

Exemplos
 Qual o custo das comparações (qual o nº de
comparações realizadas)?
As 2 comparações não são feitas ao mesmo tempo.
T(1) = 1
T(n) = 1 + T(n/2) para n > 1.
Resolvendo a recorrência temos:
T(n) = log n + 1 = O(log n)
TEORIA DA COMPUTAÇÃO

Exemplo: Algoritmo quick sort


O algoritmo de ordenação rápida procura resolver o
problema de ordenação por partes:

Inicialmente o algoritmo coloca em sua posição correta um
elemento arbitrário x (pivô). Ex: o primeiro elemento do
vetor ou o elemento do meio.

Se o elemento x ocupa a posição i do vetor, fazemos com
que os elementos v[0], ..., v[i – 1] sejam menores que x e
que todos os elementos v[i + 1], ..., v[n-1] sejam maiores
do que x.

Esses subproblemas são resolvidos recursivamente,
cada vez com vetores menores até os vetores que devem
ser ordenados terem 0 ou 1 elemento (fim da ordenação)
TEORIA DA COMPUTAÇÃO

Exemplo: Algoritmo quick sort


Algoritmo para o particionamento
1. Escolha arbitrariamente um pivô x
2. Percorra o vetor a partir da esquerda até que
v[i] ≥ x
3. Percorra o vetor a partir da direita até que
v[j] ≤ x
4. Troque v[i] com v[j].
5. Continue este processo até os apontadores i e j se
cruzarem
TEORIA DA COMPUTAÇÃO

Exemplo: Algoritmo quick sort


O pivô x é escolhido como sendo:
• O elemento central:v[(i+j) / 2].
TEORIA DA COMPUTAÇÃO

Exemplo: Algoritmo quick sort

void swap(int* a, int* b) {


int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
TEORIA DA COMPUTAÇÃO

Exemplo: Algoritmo quick sort


int partition(int vec[], int left, int right) {
int i, j;
i = left;
for (j = left + 1; j <= right; ++j) {
if (vec[j] < vec[left]) {
++i;
swap(&vec[i], &vec[j]);
}
}
swap(&vec[left], &vec[i]);
return i;
}
TEORIA DA COMPUTAÇÃO

Exemplo: Algoritmo quick sort


void quickSort(int vec[], int left, int right) {
int r;
if (right > left) {
r = partition(vec, left, right);
quickSort(vec, left, r - 1);
quickSort(vec, r + 1, right);
}
}
TEORIA DA COMPUTAÇÃO

Exemplo: Algoritmo quick sort


Melhor caso: Quando o particionamento divide o vetor
a cada chamada em dois subproblemas de tamanhos
aproximadamente iguais a n/2, que produz a seguinte
relacao de recorrencia:
T(1) = 1
T(n) = 2T(n/2) + n , sendo n o tempo necessário para
particionar o vetor

Resolvendo esta relação, acha-se a complexidade do


QuickSort no melhor caso, ou seja, O(nlogn).
TEORIA DA COMPUTAÇÃO

Exemplo: Algoritmo quick sort


Pior caso: Quando o algoritmo de particionamento
produz a cada chamada um subproblema de tamanho
n-1 e outro de tamanho 1. Nesse contexto pode-se
extrair a seguinte relacao de recorrencia:
T(1) = 1
T(n) = T(n-1) + n
Resolvendo esta relação, acha-se a complexidade do
QuickSort no pior caso, ou seja, O(n2).
TEORIA DA COMPUTAÇÃO

Classificação dos problemas de decisão (PD)


 Também podemos analisar a complexidade de um
algoritmo de MT:
M1 = “Sobre a cadeia de entrada w:
1. Faça uma varredura na fita e rejeite se for encontrado
algum 0 à direita de algum 1.
2. Repita se existem ambos, 0s e 1s, na fita:
2.1. Faça uma varredura na fita, cortando um único 0 e
um único 1.
3. Se ainda permanecerem 0s após todos os 1s cortados ou
se ainda permanecerem 1s após todos os 0s cortados,
rejeite. Caso contrário, se não houver 0s nem 1s sobre a
fita, aceite.”
TEORIA DA COMPUTAÇÃO
Classificação dos problemas de decisão (PD)
 Também podemos analisar a complexidade de um
algoritmo de MT:
M1 = “Sobre a cadeia de entrada w:
1. Faça uma varredura na fita e rejeite se for encontrado
O(n) algum 0 à direita de algum 1.
Como a cada 2. Repita se existem ambos, 0s e 1s, na fita:
varredura são
cortados 2 símbolos,
podem ocorrer no 2.1. Faça uma varredura na fita, cortando um único 0 e
máximo n/2 varreduras.
(n/2) O(n) = O(n2) um único 1. Cada varredura usa O(n) passos
3. Se ainda permanecerem 0s após todos os 1s cortados ou
se ainda permanecerem 1s após todos os 0s cortados,
O(n)
rejeite. Caso contrário, se não houver 0s nem 1s sobre a
fita, aceite.

O tempo total de M1 sobre entrada de comprimento n é O(n2)


TEORIA DA COMPUTAÇÃO

Classificação dos problemas de decisão (PD)


 Anteriormente, estudamos problemas para os quais
não é possível obter uma solução algorítmica.
 Sabemos que alguns problemas apesar de solúveis,
não podem ser resolvidos em qualquer sentido prático
pelos computadores, devido às suas excessivas
exigências de tempo de processamento.
 Hoje em dia as máquinas resolvem com eficiência
problemas mediante algoritmos que têm como
máximo uma complexidade ou custo computacional
polinomial (resolvidos em tempo tolerável).
 Já os algoritmos de tempo exponencial raramente são
úteis (resolvidos para instâncias pequenas).
TEORIA DA COMPUTAÇÃO

Classificação dos problemas de decisão (PD)


 Classe P (tempo polinomial determinístico):
• Conjunto de problemas considerados rápidos.
• Qualquer problema deste conjunto pode ser
resolvido por um algoritmo com tempo de execução
polinomial, ou seja, O(nk) sendo K uma constante
maior do que zero.
• Podem ser resolvidos em tempo polinomial por uma
MT determinística de uma única fita.
• P corresponde aproximadamente à classe de
problemas que são realisticamente solúveis em um
computador.
TEORIA DA COMPUTAÇÃO

Classificação dos problemas de decisão (PD)


 Exemplo: CAM = {<G, s, t>| G é um grafo
direcionado que tem um caminho direcionado de s
para t}

s
t

N é o número de nós em G
TEORIA DA COMPUTAÇÃO

Classificação dos problemas de decisão (PD)


 Exemplo: CAM = {<G, s, t>| G é um grafo
direcionado que tem um caminho direcionado de s
para t}
M = “Sobre a cadeia <G, s, t> onde G é um grafo direcionado
com nós s e t:
1. Ponha uma marca sobre o nó s
2. Repita o seguinte até que nenhum nó adicional seja
marcado:
2.1. Faça uma varredura em todas as arestas de G. Se uma
aresta (a, b) for encontrada de um nó marcado a para um nó
não marcado b, marque o nó b.
3. Se t estiver marcado, aceite. Caso contrário, rejeite.
TEORIA DA COMPUTAÇÃO

Classificação dos problemas de decisão (PD)


 Exemplo: CAM = {<G, s, t>| G é um grafo
direcionado que tem um caminho direcionado de s
para t}
M = “Sobre a cadeia <G, s, t> onde G é um grafo direcionado
com nós s e t:
O(1) 1. Ponha uma marca sobre o nó s
2.1 pode ser 2. Repita o seguinte até que nenhum nó adicional seja
executado no
máximo n vezes, marcado:
pois em cada vez,
exceto na última, 2.1. Faça uma varredura em todas as arestas de G. Se
ele marca um nó
adicional em G. 2uma aresta (a, b) for encontrada de um nó marcado a
Logo, n O(n) = O(n para
) um nó não marcado b, marque o nó b. O(n)
O(1) 3. Se t estiver marcado, aceite. Caso contrário, rejeite.
TEORIA DA COMPUTAÇÃO

Classificação dos problemas de decisão (PD)


 Classe NP (tempo polinomial não determinístico):
• Conjunto de problemas para os quais não foi
descoberto algoritmo de tempo polinomial para eles.
• Mas eles podem ser verificados em tempo
polinomial.
• Podem ser resolvidos em tempo polinomial por uma
MT não determinística.
• Classe das linguagens para as quais a pertinência
pode ser verificada rapidamente (em tempo
polinomial).
TEORIA DA COMPUTAÇÃO

Classificação dos problemas de decisão (PD)


 Exemplo:Verificar se um número é composto (não
primo), ou seja, se ele é o produto de 2 números
inteiros maiores que um.
Compostos = {x | x = pq, para inteiros p, q > 1}

Para nºs grandes, esse é um programa muito difícil de


resolver de forma eficiente. Mas podemos facilmente
verificar que um nº é composto se for dado um divisor
desse número.
TEORIA DA COMPUTAÇÃO

Classificação dos problemas de decisão (PD)


 Exemplo:Verificar se um número é composto (não
primo), ou seja, se ele é o produto de 2 números
inteiros maiores que um.
Compostos = {x | x = pq, para inteiros p, q > 1}

Ilustração: se eu disser que o número 13.717.421


pode ser escrito como o produto de dois outros
inteiros, você provavelmente demorará para provar
isso; contudo, se lhe assoprarem que ele é o produto
de 3.607 por 3.803, você seria capaz de muito
rapidamente verificar tal fato.
TEORIA DA COMPUTAÇÃO

Classificação dos problemas de decisão (PD)


 Exemplo: CLIQUE = {<G, K> | G é um grafo não
direcionado com um k-clique}
 Um clique em um grafo não-direcionado é um
subgrafo no qual todo par de nós está conectado
por uma aresta. Um k-clique é um clique que
contém k nós.

Grafo com um 5-clique (


Subgrafo conectado por
Linha preta)
TEORIA DA COMPUTAÇÃO

Classificação dos problemas de decisão (PD)


 Exemplo: CLIQUE está em NP
M = “Sobre a cadeia <G, k> onde G é um grafo :
1. Não deterministicamente selecione um subconjunto c de k
nós em G
2. Teste se G contém todas as arestas conectando nós em c.
3. Se sim, aceite; Caso contrário, rejeite.
 Verificador V para CLIQUE
V = “Sobre a cadeia <<G, k>, c> :
1. Teste se c é um conjunto de k nós em G.
2. Teste se G contém todas as arestas conectando nós em c.
3. Se ambos os testes são positivos, aceite. Senão, rejeite.
TEORIA DA COMPUTAÇÃO

P x NP
 Um dos maiores problemas não resolvidos em CC e
matemática é se P = NP.
 O bom senso sugere que P é apenas uma pequena
parte de NP. A maioria dos pesquisadores acreditam
que as 2 classes não são iguais porque as pessoas
investiram esforços enormes para encontrar
algoritmos polinomiais para certos problemas em NP,
sem sucesso.
 No entanto, alguns acreditam que P seja, talvez, igual
a NP. Isso porque somos incapazes de provar a
existência de uma única linguagem em NP que não
esteja em P.
TEORIA DA COMPUTAÇÃO

P x NP
 O problema pergunta se existem problemas matemáticos
cuja resposta pode ser verificada em tempo polinomial
(NP), que não possam ser resolvidos em tempo polinomial.
 Se essas classes fossem iguais, qualquer problema
polinomialmente verificável seria polinomialmente
decidível.
 O problema parte da constatação que são muito freqüentes
as situações em que parece ser muito mais rápido verificar
solução do que achar um processo de resolução, e então
pergunta: isso sempre ocorre, ou simplesmente ainda não
descobrimos um modo de resolvê-los rapidamente?
TEORIA DA COMPUTAÇÃO

Redutibilidade
 Usamos reduções de tempo polinomial para
estudar a complexidade de vários problemas
importantes e aparentemente difíceis da classe NP.
 Podemos dizer que f é uma redução polinomial do
problema A para o problema B se for uma redução
polinomial entre as linguagens correspondentes,
isto é, se transforma em tempo polinomial,
instâncias do problema A para instancias do
problema B, de tal forma que x é uma instancia do
problema A com resposta “sim” se e somente se
f(x) for uma instância do problema B q também
fornece a resposta “sim”.
TEORIA DA COMPUTAÇÃO

Redutibilidade
 Se A é redutível a B e tem um algoritmo polinomial
que resolve B, esse algoritmo também resolve A em
tempo polinomial, uma vez que os passos
responsáveis pela redução e o algoritmo que
resolve a instância de B podem ser executados em
tempo polinomial.
 Se A se reduz a B em tempo polinomial e existe
algoritmo que resolve B em tempo polinomial,
então A também pode ser resolvido em tempo
polinomial.
TEORIA DA COMPUTAÇÃO

Problemas NP-completo
 É um subconjunto dos problemas NP que têm a
complexidade inerente a todos os problemas dessa
classe. Uma solução de tempo polinomial para um
problema NP-Completo resolveria toda a classe NP.
 Uma linguagem L é NP-completa se:
 L pertence a NP
 E para qualquer linguagem L’ que pertence a NP
existe alguma redução polinomial de L’ para L
 Propriedade de completude: todos os problemas em
NP podem ser reduzidos a eles (problemas NP-
completos) por meio de reduções de tempo polinomial.
TEORIA DA COMPUTAÇÃO

Problemas NP-completo
 Para provar que um problema é NP-completo:
 Mostre que o problema está em NP.
 Mostre que um problema NP-completo conhecido
pode ser polinomialmente reduzido para ele.

 NP-difícil: Alguns problemas são tão difíceis que


embora possamos provar que existe um problema NP-
completo que se reduz a ele, não podemos provar que
ele está em NP. Nesse caso, dizemos que L é NP-difícil.
TEORIA DA COMPUTAÇÃO

Referências

 ZIVIANI, Nivio. Projeto de Algoritmos com


implementações em Pascal e C. Ed. Cengage
Learning, 2004. ISBN: 8522103909.

 Sipser, M.; Introdução à Teoria da Computação. Ed.


Thomson, 2007. ISBN: 9878522104994.

S-ar putea să vă placă și