Faculdade Campo Limpo Paulista Mestrado em Ciência da Computação Complexidade de Algoritmos – Avaliação 3 1. (2,0): O algoritmo de ordenação MergeSort divide um conjunto a ser ordenado na metade, ordena indutivamente as duas metades e, por fim, intercala as duas metades para obter a solução final. Escreva um algoritmo, digamos MergeSort4, que divide o conjunto a ser ordenado em quatro partes, ordena indutivamente cada uma delas e faz as intercalações necessárias para obter a solução final. Calcule a complexidade deste algoritmo. Ela é melhor, igual ou pior que a versão original do MergeSort? Você poderá utilizar, na sua solução, o algoritmo Intercala (A, i, m, f) que intercala os elementos de um vetor A, situados entre i e m com os elementos situados entre m + 1 e f. Lembramos que a complexidade do algoritmo Intercala é igual a n – 1, onde n é a quantidade de elementos de i até f. SOLUÇÃO Algoritmo MergeSort4 (A, i, f) Entrada: A, um vetor; i e f são índices do vetor, i Saída: Ordena “in-loco” o vetor A do índice i até o índice f. { m1 := (i + f)/4; m2 := (i + f)/2; m3 := 3*(i + f)/4; MergeSort4 (A, i, m1); MergeSort4 (A, m1 + 1, m2); MergeSort4 (A, i, m2 + 1, m3); MergeSort4 (A, m3 + 1, f); Intercala (A, i, m1, m2); Intercala (A, m2 + 1, m3, f); Intercala (A, i, m2, f) } Complexidade Seja n = f – i + 1, a quantidade de elementos. Cada uma das 4 chamadas recursivas a MergeSort4 tem complexidade igual a T(n/4). Cada uma das 2 primeiras chamadas a Intercala tem complexidade igual a n/2 – 1. A última chamada a Intercala tem complexidade igual a n – 1. Portanto, a seguinte relação de recorrência define a complexidade do algoritmo: T(n) = 4T(n/4) + 2(n/2 – 1) + n – 1, ou seja, T(n) = 4 T(n/4) + 2n – 3 T(1) = 1. Resolvendo esta relação de recorrência chegamos a T(n) = O (n log n). Ou seja, o algoritmo MergeSort4 tem complexidade igual ao algoritmo MergeSort. 2. (2,0): Desenvolva um algoritmo O ( (n + m) log n) para determinar se um conjunto, S1 de m elementos está contido em um conjunto S2 de n elementos. Um conjunto S1 ⊆ S2 se ∀ x ∈ S1 ocorre de x ∈ S2. Obs.: você pode utilizar na sua solução algoritmos para ordenação e busca estudados. Algoritmo EstáContido (S1, m, S2, n) Entrada: S1 um conjunto de m elementos e S2 um conjunto elementos. Saída: Verdadeiro caso S1 ⊆ S2 e falso, caso contrário. { MergeSort (S2, 1, n); de n i := 1; enquanto (i ≤ m e BuscaBinária (S2, n, S1[i]) = 1) ) i := i + 1; se (i ≤ m) retornar falso senão retornar verdadeiro } Complexidade (pior caso) A ordenação (MergeSort) tem complexidade O (n log n). Cada busca binária em S2 tem complexidade O (log n). No pior caso m buscas serão feitas, o que conduz à complexidade O (m lon n). No total temos que a complexidade do algoritmo é igual a T(n) = O (n log n) + O (m log n) = O (n log n + m log n) = O ( (n + m) log n). 3. (2,0): Suponha que alguém lhe deu de presente um algoritmo A(S, k) que decide em tempo polinomial o problema da soma de subconjunto (SUBSET-SUM). Isto é, o algoritmo A retorna 1 caso exista um subconjunto S’ de S tal que a soma dos elementos de S’ é igual a k, e retorna 0 caso contrário. Descreva como usar este algoritmo para escrever um algoritmo polinomial B(S, k) que retorna um subconjunto solução S’. SOLUÇÃO A idéia executar o algoritmo A passando como argumentos um conjunto S e um inteiro k. Se o algoritmo A retornar zero então o problema está resolvido, sendo neste caso o conjunto S’ = {}. Caso contrário, para cada elemento de S, nós o retiramos de S e executamos A com argumentos S e k. Se o algoritmo A retornar 0 nós retornamos o elemento retirado para o conjunto S, pois ele faz parte do conjunto solução. Ao final do processo o conjunto solução é S’ = S. Algoritmo B (S, k) Entrada: S, um conjunto de números e k, um inteiro. Saída: Retorna S’, um subconjunto de S cuja soma é igual a k. { se ( A(S, k) = 0 ) S’ := {} senão { para i := 1 até |S| faça { Retirar de S o elemento si; se ( A(S, k) = 0 ) Retornar o elemento si para o conjunto S } S’ := S } retornar S’ } Sendo O(nc), c constante, a complexidade do algoritmo A, o algoritmo B terá complexidade O (n). O(nc) = O(n c+1), portanto ele é polinomial. 4. (2,0) O problema de decisão CONJUNTO-INDEPENDENTE pode ser assim definido: dado um grafo G = (V, E) e um inteiro k ≥ 0, determinar se G tem um conjunto independente I de tamanho igual a k. Um conjunto independente I é um subconjunto de V tal que para quaisquer dois vértices v e w em I não existe uma aresta em (v, w) em E. a) Descreva a linguagem LCI, a linguagem das cadeias que representam instâncias positivas do problema de decisão CONJUNTOINDEPENDENTE. b) Mostre que LCI ∈ INP. c) Mostre que LCI ∈ INP-difícil. Se você não conseguir mostrar isto, pelo menos diga como isto pode ser feito. SOLUÇÃO a) Nós codificaremos instâncias do problema CONJUNTO-INDEPENDENTE assim: #Descrição do grafo G = (V, E)#k#. Por sua vez, um grafo como o dafigura a seguir será descrito como 1,2,3,4$(1,2),(1,3),(2,3),(3,4) o que conduz a uma cadeia #1,2,3,4$(1,2),(1,3),(2,3),(3,4)#3# que representa uma instância do problema CONJUNTO-INDEPENDENTE dada acima. Sendo ∑ = { #, $, ,, (, ), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, nós definimos LCI = { x ∈ ∑*, x = #grafo G#k# | existe conjunto independente em G de tamanho igual a k } b) Nós afirmamos que existe um algoritmo de verificação A que aceita LCI em tempo polinomial no pior caso. Logo LCI ∈ INP. Algoritmo A (x, y) Entrada: x ∈ ∑*, x = #grafo G#k# e y (certificado), um conjunto de vértices. Saída: 1 se y é um conjunto independente de G de tamanho igual a k e 0, caso contrário. { se o tamanho de y for igual a k se para cada combinação de vértice (v, w) em y não houver aresta em G retornar 1 senão retornar 0 senão retornar 0 } O total de combinações possíveis de vértices é igual à combinação de n elementos 2 a 2 que é igual a n (n – 1) / 2, onde n representa a quantidade de vértices. O algoritmo acima é O (n2), portanto é polinomial. Além disso, observe que |y| = n = O (n). c) A idéia é escolher uma linguagem (problema) INP-completo e mostrar que ela pode ser reduzida em tempo polinomial à LCI. Escolhemos LVC = { x ∈ ∑*, x = #grafo G#k# | existe cobertura de vértices de tamanho igual a k em G }. Sabemos que LVC ∈ INP-completo. Afirmamos que LVC ≤p LCI. Logo, concluímos que LCI ∈ INP-difícil. Prova de que LVC ≤p LCI. Idéia do algoritmo que reduz uma instância positiva de LVC a uma instância positiva de LCI. Algoritmo Reduz_Lvc_Lci (x) Entrada: x ∈ ∑*, x = #grafo G=(V, E)#k# Saída: z ∈ ∑*, z = #grafo G=(V, E)#k’# { 1 – k’ = | V | - k; 3 – z := #grafo G#k’# 4 – retornar z } O algoritmo Reduz_Lvc_Lci tem complexidade O (n), onde n é tamanho da cadeia x. Logo, é polinomial. Falta mostrar que x ∈ LVC se e somente se z ∈ LCI. i) Mostrando que x ∈ LVC ⇒ z ∈ LCI. Seja x ∈ LVC. ⇒ existe no grafo G = (V, E) uma cobertura de vértices, digamos C, de tamanho k. ⇒ Toda aresta em E possui pelo menos um vértice em C. ⇒ O conjunto I = V – C só possui vértices entre os quais não há aresta em E. ⇒ I é um conjunto independente no grafo G. ⇒ O tamanho de I é k’ = |V| - k ⇒ z = #grafo G#k’# ∈ LCI. ii) Mostrando que z ∈ LCI ⇒ x ∈ LVC. Seja z ∈ LCI. ⇒ existe no grafo G = (V, E) um conjunto independente, digamos I, de tamanho k’. ⇒ Para quaisquer dois vértices v e w em I não existe uma aresta em (v, w) em E. ⇒ O conjunto C = V – I é tal que toda aresta (v, w) em E ocorre de v ∈ C ou w ∈ C. ⇒ C é uma cobertura de vértices no grafo G. ⇒ O tamanho de C é k = |V| - k’ . ⇒ x = #grafo G#k# ∈ LVC. 5. (2,0): Para cada afirmação a seguir responda se ela é verdadeira, falsa ou talvez (em caso de não se conhecer cientificamente a resposta). Justifique com poucas palavras a sua resposta. a) Se L ∈ IP então L ∈ INP. b) IP = INP. c) Existe linguagem L ∈ INP tal que L ∉ IP. d) Se L ∈ INP-completo então L ∈ INP-difícil. a) Verdadeira. Foi mostrado em aula que, para qualquer linguagem L ∈ IP, é possível escrever um algoritmo de verificação polinomial que aceita L. Logo L ∈ INP. b) Talvez. Esta é uma das maiores questões não resolvidas em Ciência da Computação. c) Talvez. Se soubessemos da exisência de uma linguagem L ∈ INP tal que L ∉ IP então a questão IP versus INP estaria resolvida com IP ≠ INP. d) Verdadeira. Isto decorre imediatamente da definição da classe INP-completo. Uma linguagem L ∈ INP-completo se L ∈ INP e L ∈ INP-difícil.