Módulo 12 4.5 Complexidade de Problemas 4.5.1 Complexidade da Ordenação 4.5.2 Problemas np-completos: o Problema do Caixeiro Viajante 4.5.3 Problemas Indecidíveis: o Problema da Correspondência de Post DCC001 - 2011-2 DCC 001 Programação de Computadores 2º Semestre de 2011 Prof. Osvaldo Carvalho 1 Complexidade da Ordenação DCC001 - 2011-2 2 Complexidade da Ordenação O tempo necessário para ordenar um vetor é 2 O n para o SelectSort O ( n log( n)) para o MergeSort Existiriam algoritmos com curvas de crescimento melhores do que o MergeSort? Vamos estudar o comportamento de algoritmos de ordenação por comparação (existem outros tipos de algoritmos que, por exemplo, tiram partido das chaves serem formadas por 3 dígitos) DCC001 - 2011-2 3 Algoritmos de Ordenação por Comparações Algoritmos de ordenação decidem suas próximas ações a partir de comparações entre elementos do vetor de entrada Um algoritmo correto deve ser capaz de ordenar qualquer permutação de [1..n] Os diagramas dos próximos slides foram produzidos DCC001 - 2011-2 “aparelhando” algoritmos de ordenação para registro da sequência de comparações realizada submetendo todas as permutações de [1 2 3] a cada algoritmo 4 Árvore de Decisões Select Sort Comparação de elementos de índices 2 e 3 no vetor original Resultado de Comparação DCC001 - 2011-2 Vetor ordenado 5 Árvore de Decisões Bolha DCC001 - 2011-2 6 Árvore de Decisões QuickSort DCC001 - 2011-2 7 Requisitos para uma Árvore de Decisões para Ordenação por Comparação Permutação 1 ? Árvore de Decisões Algoritmo Arbitrário Permutação 1 Permutação 1 … Permutação n! DCC001 - 2011-2 8 Árvores Binárias (2 filhos no máximo) Raiz DCC001 - 2011-2 “Folhas” não têm filhos 9 Profundidade em uma Árvore p=0 p=1 p=2 p=3 DCC001 - 2011-2 10 Profundidade Máxima e Número de Folhas de uma Árvore Binária p DCC001 - 2011-2 No máximo 2p folhas 11 Profundidade Mínima Árvore de decisões para ordenar n itens têm obrigatoriamente n! folhas Sua profundidade máxima mínima deve ser tal que p 2 n! p log 2 n! log 2 (1) log 2 (2) log 2 (n) DCC001 - 2011-2 12 A soma dos logaritmos é a Soma de Riemann pela Esquerda de log(n) DCC001 - 2011-2 13 Complexidade Mínima para Ordenação n P log 2 i log 2 x dx i 1 n 1 x n n 1 1 (n log 2 n x log 2 x ) (1. log 2 (1) ) ln( 2) ln( 2) ln( 2) n 1 n log 2 n ln( 2) Conclusão: A complexidade mínima para qualquer algoritmo de ordenação por comparações é On log n O MergeSort atinge este limite DCC001 - 2011-2 14 O Problema do Caixeiro Viajante DCC001 - 2011-2 15 O Problema do Caixeiro Viajante Um caixeiro viajante quer visitar cidades e retornar ao ponto de partida, percorrendo a menor distância possível, sem passar duas vezes pela mesma cidade Ele conhece a distância entre duas cidades quaisquer de seu roteiro Quando não existir uma estrada entre duas cidades, atribui-se o valor infinito à distância entre elas DCC001 - 2011-2 n 16 O Problema do Candidato Como minimizar o custo de visitar, de avião, todas as capitais brasileiras, sem pousar duas vezes na mesma cidade? DCC001 - 2011-2 17 Um problema com 5 cidades 1 Qual é o melhor 6 roteiro? 5 2 2 3 3 3 4 3 4 DCC001 - 2011-2 7 3 18 Um Caminho Custo = 19 5 1 2 6 2 3 3 3 4 3 4 DCC001 - 2011-2 7 3 19 Outro Caminho 1 Custo = 22 2 6 5 2 3 3 3 4 3 4 DCC001 - 2011-2 7 3 20 O Problema do Caixeiro Viajante Custo = 15 Caminho ótimo! 5 1 2 6 2 3 3 3 4 3 4 DCC001 - 2011-2 7 3 21 Um problema com 8 cidades 1 8 12 9 9 14 8 11 13 1 7 12 2 3 5 12 4 11 6 12 3 6 12 15 15 DCC001 - 2011-2 9 10 4 5 1 22 Um caminho 1 Custo = 81 8 9 14 8 12 9 11 13 1 7 12 2 3 5 12 4 11 6 12 3 6 12 15 15 DCC001 - 2011-2 9 10 4 5 1 23 Outro caminho (o pior) 1 Custo = 98 8 12 9 9 14 8 11 13 1 7 12 2 3 5 12 4 11 6 12 3 6 12 15 15 DCC001 - 2011-2 9 10 4 5 1 24 Caminho Ótimo 1 Custo: 64 8 14 8 12 9 9 11 13 1 7 12 2 3 5 12 4 11 6 12 3 6 12 15 15 DCC001 - 2011-2 9 10 4 5 1 25 Solução “Força Bruta” para o Caixeiro Viajante 1. Gerar todas as alternativas de rota = todas as permutações de cidades, excetuando a cidade de partida 2. Para cada rota, calcular seu custo total 3. Escolher a rota de menor custo DCC001 - 2011-2 26 O Programa CaixeiroViajante.sce Primeira Versão // // // // // DCC001 - 2011-2 Lê a matriz de distâncias Gera todas as rotas possíveis Calcula o custo de cada rota Seleciona a de menor custo Imprime o resultado 27 Arquivo com a matriz de distâncias fscanfMat só lê números Como as distâncias são positivas, usamos -1 para representar ∞ DCC001 - 2011-2 28 Leitura da matriz de distâncias // Lê a matriz de distâncias Dist = ... fscanfMat(uigetfile("*.txt",pwd(),"Distâncias")); // Substitui -1 por %inf Dist(Dist==-1) = %inf; Elementos de Dist onde Dist==-1 DCC001 - 2011-2 29 Obtenção das rotas e cálculo dos custos [nl,nc] = size(Dist); //nl deve ser igual a nc Rotas = permutations(2:nc); // Calcula o custo de cada rota [NL,NC] = size(Rotas); for i = 1:NL Custo(i) = cost(Dist,[1 Rotas(i,:) 1]); end Justaposição de 1 às rotas geradas DCC001 - 2011-2 30 A função cost function c = cost(D,path) c = 0; for i=1:length(path)-1 c = c + D(path(i),path(i+1)); end endfunction DCC001 - 2011-2 31 A função permutations Cabeçalho Function p = permutations(A) // gera uma matriz p onde // cada linha é uma permutação de A endfunction DCC001 - 2011-2 32 Permutações Para um problema com 4 cidades, as rotas a serem examinadas são (lembrando que a cidade 1 é o início e o fim do percurso) 2. 3. 4. 2. 4. 3. 3. 2. 4. 3. 4. 2. 4. 2. 3. 4. 3. 2. DCC001 - 2011-2 33 Algoritmo para gerar permutações de um vetor Se o vetor é de tamanho 1, ele já é a única permutação; senão, “Separar” o primeiro elemento do vetor; Gerar todas as permutações dos elementos restantes, e concatená-las ao elemento separado Repetir este passo para os demais elementos do vetor DCC001 - 2011-2 34 Exemplo de Geração de Permutações Vetor = [2 3 4] Passos: Separar o elemento 2, e gerar todas as permutações de [3 4]; concatenar 2 às permutações obtidas; Separar o elemento 3, e gerar todas as permutações de [2 4]; concatenar 3 às permutações obtidas; Separar o elemento 4, e gerar todas as permutações de [2 3]; concatenar 4 às permutações obtidas; DCC001 - 2011-2 35 A função permutations function p = permutations(A) if length(A) == 1 then p = A; else p = []; for i = 1:length(A) B = permutations(OneOut(A,i)); [nl,nc] = size(B); for j = 1:nl p = [p ; [A(i) B(j,:)]]; end end end endfunction DCC001 - 2011-2 36 A função OneOut function b = OneOut(A,i) x = 1:length(A); b = A(x ~= i); endfunction DCC001 - 2011-2 37 Caixeiro Viajante Complexidade Solução “força bruta”: Gerar todas as permutações das cidades Para cada uma, calcular a distância total Escolher o roteiro com a menor distância total Problema com a força bruta: são (n-1)! roteiros Para o exemplo com 5 cidades, são 4! = 24 possibilidades, mas Para o problema das capitais brasileiras, são 26! = ~ 4 x 1026 possibilidades a serem examinadas! DCC001 - 2011-2 38 Caixeiro Viajante Complexidade Existiriam soluções melhores? Sim, mas a melhor encontrada até hoje é On 2 2 n Isto é pior do que qualquer potência de n, ou que qualquer polinômio em n DCC001 - 2011-2 39 As Classes P e NP DCC001 - 2011-2 40 Comparação de funções de complexidade Função de complexidade n 10 20 30 40 50 60 0,00001 0,00002 0,00003 0,00004 0,00005 0,00006 segundos segundos segundos segundos segundos segundos 2 0,0036 0,0025 0,0016 0,0009 0,0004 0,0001 segundos segundos segundos segundos segundos segundos n3 0,216 0,125 0,064 0,027 0,008 0,001 segundos segundos segundos segundos segundos segundos n5 1,7 24,3 3,2 0,1 segundos segundos segundos minutos 2n 17,9 1,0 0,001 segundos segundos segundos n 3 DCC001 - 2011-2 Tamanho da Instância do Problema n 58 0,059 segundos minutos 6,5 anos 5,2 minutos 13,0 minutos 12,7 dias 35,7 anos 366 séculos 3855 séculos 2 × 108 séculos 1,3 × 1013 séculos 41 Efeito de Progressos Tecnológicos Maior instância que um computador resolve em 1 hora Computador Computador Função de Computador 100x mais 1000x mais complexidade Atual rápido rápido N 100 N 1000 N n DCC001 - 2011-2 n2 M 10 M 31,6 M n3 Z 4,64 Z 10 Z n5 W 2,5 W 3,98 W 2n X X + 6,64 X + 9,97 3n Y Y + 4,19 Y + 6,29 42 Problemas de Decisão Teóricos de complexidade preferem trabalhar com problemas de decisão, cuja resposta é Sim ou Não O problema de decisão associado ao Caixeiro Viajante é: DCC001 - 2011-2 Dado um conjunto de n cidades e suas distâncias, existe pelo menos uma rota com custo menor que um dado valor B? 43 Satisfatibilidade (SAT) Dados: um conjunto de variáveis booleanas v1,…,vn, e um conjunto de cláusulas, que são expressões com OR destas variáveis, como v3+v7’+v10 Existe um conjunto de valores para v1,…,vn tal que o AND de todas as cláusulas tenha o valor True? DCC001 - 2011-2 44 Verificando uma Solução de um Problema de Decisão A vantagem de um problema de decisão é a possibilidade de definição de um problema associado, que somente verifica uma solução apresentada O problema de verificação pode ter complexidade menor do que o problema de decisão P.Ex, é possível verificar se uma dada rota tem custo menor que B em tempo linear DCC001 - 2011-2 45 A Classe NP de Problemas de Decisão Um problema de decisão está na classe de complexidade P : quando existe um algoritmo polinomial que o resolve; NP: quando o problema de verificação associado a ele tem complexidade polinomial, como é o caso do Caixeiro Viajante e do SAT NP não quer dizer Não Polinomial, mas sim Non-deterministic Polynomial, referindo-se a um artifício teórico utilizado para se ter o problema de verificação “resolvendo” por sorteio o problema de decisão DCC001 - 2011-2 46 Problemas NP-completos O Caixeiro Viajante e o SAT são exemplos de problemas NP-completos, Um problema Π é NP-completo quando qualquer problema da classe NP pode ser transformado em Π DCC001 - 2011-2 47 P = NP? Apesar dos esforços dos mais brilhantes e persistentes cientistas da computação, ninguém conseguiu DCC001 - 2011-2 provar que um problema como o SAT não pertence à classe P, apresentando um algoritmo polinomial que o resolva (ou que resolva qualquer problema NP-completo) provar (como fizemos com algoritmos de ordenação) que não existe tal algoritmo 48 P = NP? Se você Provar que não existe nenhum algoritmo polinomial para qualquer problema NP-Completo, Ou Encontrar um algoritmo polinomial para um problema NP-Completo, Você terá de imediato 1 milhão de dólares, glória e fama eternas DCC001 - 2011-2 49 Problemas Indecidíveis DCC001 - 2011-2 50 O Problema de Emil Post Tipo 1 100 100 100 11100 100 11 1 Tipo 2 00 00 100 0 100 100 100 100 Tipo 3 11 11 00 1 00 00 00 00 Considere um estoque ilimitado de dominós de um número finito de tipos Todos os dominós de um tipo têm um mesmo string de 0s e 1s na parte de cima e outro na parte de baixo O problema de Post consiste em obter uma sequência de dominós tal que os strings formados pela concatenação dos strings superiores e inferiores sejam iguais DCC001 - 2011-2 51 O Problema de Post Solução com 7 dominós 100 1 100 1 1 00 0 100 100 1 100 1 1 00 1 00 0 100 0 100 1001100100100 DCC001 - 2011-2 52 O Problema de Post Algoritmo força-bruta: n = 0; repita n = n+1 teste todas as sequências com n dominós até encontrar uma solução DCC001 - 2011-2 53 Geração de sequências n=1 [1] [2] [3] n=2 [1 1] [1 2] [1 3] [2 1] [2 2] [2 3] [3 1] [3 2] [3 3] n=3 [1 1 1] [1 1 2] [1 1 3] [1 2 1] [1 2 2] [1 2 3] [1 3 1]... DCC001 - 2011-2 54 Método para Geração das Sequências É como contar: os tipos de dominós parecem algarismos em um sistema de numeração Se o algarismo menos significativo for menor que T (nro. de tipos), soma-se 1 a ele; Senão, coloca-se 1 no algarismo menos significativo, e propagamos o vai-um, aumentando o número de algarismos se for o caso Exemplos com T = 3 Suc([2]) = [3]; Suc([3]) =[1 1] Suc([2 2]) = [2 3]; Suc([2 3]) = [3 1] Suc([3 3]) = [1 1 1] DCC001 - 2011-2 55 O programa Post.sce // Leitura do problema de Post [nTypes Up Down] = ReadPostProblem(); WritePostProblem(Up,Down); found = %f; seq = []; while ~found seq = Sucessor(seq,nTypes); upString = strPost(Up,seq); dnString = strPost(Down,seq); found = upString == dnString; if found then WritePostSolution(seq,Up,Down); end end DCC001 - 2011-2 56 A função Sucessor function s = Sucessor(r,nTypes) // retorna o sucessor da sequência r VaiUm = 1; for i = length(r):-1:1 if VaiUm > 0 then if r(i) < nTypes then r(i) = r(i) + 1; VaiUm = 0; else r(i) = 1; end end end if VaiUm == 1 then s = [1 r]; else s = r; end endfunction DCC001 - 2011-2 57 A função Sucessor: Exemplos de Uso -->Sucessor([],3) ans = 1. -->Sucessor([2 3 1],3) ans = 2. 3. 2. -->Sucessor([3 3 3],3) ans = 1. 1. 1. 1. DCC001 - 2011-2 58 Teste do Programa Post.sce Problema de Post: 100 0 1 1 100 00 Solução: 1001100100100 1 3 1 1 3 100 1 100 100 1 1 00 1 1 00 DCC001 - 2011-2 2 0 100 2 0 100 59 Um Problema de Post difícil 1000 0 01 0 1 101 00 001 A menor solução para o problema acima usa 206 dominós! Como geramos sequências na forma como contamos, seria contar até obter um número com 206 algarismos; em um notebook, o programa Post.sce demoraria 10112 anos para resolver! Ruim? Pois ainda pode ser bem pior! DCC001 - 2011-2 60 O Problema de Post O problema: 10 0 0 001 001 1 tem solução? Até hoje ninguém sabe! DCC001 - 2011-2 61 Problemas Indecidíveis O problema de Post pertence à classe dos problemas indecidíveis O espaço de busca em um problema np-completo como o do Caixeiro Viajante é grande, cresce explosivamente, mas Em um problema indecidível o espaço de busca é infinito! Para o problema de Post, sempre existe a possibilidade da solução ser uma sequência maior DCC001 - 2011-2 62 Conclusões Resultados teóricos do estudo de um problema podem colocar limites na complexidade de qualquer algoritmo que o resolva Problemas np-completos não têm resultados teóricos com estes limites, mas todas as soluções já encontradas são piores que qualquer polinômio Problemas indecidíveis têm como resultado teórico a não existência de nenhum algoritmo que garantidamente encontre uma solução DCC001 - 2011-2 63