Você está na página 1de 9
Projeto de Algoritmos | LinguagemC | indice Algoritmos de enumeracao Enumere a estrelas de nossa glia, tim antigo probleme ‘Often it appears that there is no beter way to solve a problems tha oy all posible solutions. This spproach,called exhaustive ear, salma! always slow but sometimes its better than no an Barberry, Problems an Algorids Para resolver certos problemas computacionais ¢ necessdrio enumerar — ou seja, fazer uma lista de — todos os objetos de um determinado tipo (por exemplo, todas as rvores binarias de busca com chaves entre 1 ¢ 999). O ndimero de objetos 6 tipicamente muito grande, e portanto sua enumeracdo consome muito tempo. Os algoritmos de enumeracdo ndo séo complexos, mas tém suas sutilezas. As versbes recursivas so particularmente diteis e interessantes. Os problemas de enumeracao estao relacionados com expresses como backtracking, busca exaustiva, forca bruta, e branch-and- bound. Sequéncias Os objetos principais deste capitulo sao sequéncizs de nimeros inteiros, como 9 51 61 4 8 2 18 97 13 22 13 por exemplo. Essas sequéncias seréo representadas por vetores. Assim, uma sequéncia como s1 5 53 ....s sera denotada simplesmente por sfl..A. Por conveniéncia, as sequéncias e vetores serao indexados a partir de 1 e nao a partir de 0, como ¢ mais comum em C. Usaremos A\ a abreviatura especial 1..1 para a sequéncia 123...1. De modo mais geral, m..1 seré nossa abreviatura para m m+ m+2.... m, Sem>n, a sequéncia é vazia, Sequéncias sdo comparadas lexico, 1 existe ital que r[1..i-1] = s{1..-1] e rfl] = 1) ( isprine (subs, K) Af (subs[&] © que faz, exatamente, a fungao ssLexConPrefixo? Como explicar o funcionamento de ssLexConPrefixo? Fis a resposta: Em outras palavras, imprime todas as sequéncias da forma x[1..k. -kk] tais que x[1..k] = subs[1.-k] ex[k#1. .kk] é uma subsequéncia nao vazia dem. .n Suponha, por exemplo, que subs [1 lista , subs[ 2] = 4, en = 9. Entdo a chamada ssLexConPrefixo (subs, 2, 7, n) imprime a A primeira linha ¢ produzida por imprime (subs,3); as trés linhas seguintes so produzidas por ssLexConPrefixo (subs, 3, 8,n); eas demais, por ssLexComPrefixo (subs, 2, 8, n) Portanto, a chamada ssLexConPrefixo (subs, @, 1, n) no cédigo de ssLexR faz exatamente o que queremos: imprime todas as subsequéncias néo vazias de 1. .n (com prefixo vazio). ‘A fungao ssLexR tem uma séria desvantagem em relagdo a sua versao iterativa: a pilha de execucdo da versdo recursiva consome bem mais espaco na memiéria que a versao iterativa (que s6 precisa de espaco para armazenar subs[@. .n+1]) sslext nvele@ 162 caracteres ASCIL ABC ABC AB AC BC ABC n bft..n] ten subs[1..k bi] valeaees e 235 6 1101 subs[1..k] aan b[1.-n] subs[1..k] de..n > bina Enumeracao de permutacées Uma pennutaci da sequéncia 1.1 € qualquer rearranjo dos termos dessa sequéncia. Em outras palavras, uma permutago de 1... qualquer sequéncia p{1 .. 1] em que cada elemento de 1.1 aparece uma e uma s6 vez, F facil verificar que hi exatamente n! permutacdes de 1..n. Por exemplo, as 24 permutacées de 1234 sao Nosso problema: Enumerar as permutacées de 1.1m, ou seja, produzir uma lista em que cada permutacio de 1.1 apareca uma e uma s6 vez. ‘A ordem em que as permutagées so enumeradas nao é muito importante, mas é natural dar preferéncia a ordem lexicogratica, Preliminares. A ideia é gerar cada permutacao a partir de sua predecessora imediata, Considere, por exemplo as permutacdes de 1. .4, Para obter a sucessora imediata da permutagdo 3 4 1 2, podemos apagar o tiltimo termo, somar 1 a0 pentiltimo, ¢ adotar o tinico valor posstvel para o tiltimo termo: 3412 342- 3424 Em geral, pode ser necessério repetir esse proceso. Por exemplo, para obter a sucessora imediata de 2 1 4 2, nao basta apagar o tiltimo termo, pois 0 valor seguinte do pentiltimo termo nao pertence ao universo 1. .4. Considere ento apagar os dois ‘ltimos termos e somar 1 a0 antepenltimo, Isso ainda nao resolve o impasse, pois ja temos um 2 entre os primeiros termos. Mas somar mais 1 ao antepentiltimo termo torna-o diferente dos anteriores e assim resolve o impasse. Por fim, basta preencher as posigées que ficaram vagas com os valores que ainda faltam, 1 4, nessa ordem: = nao, pois § nfo pertence ao universo = io, porque jd temos 2 esquerda sim! todos diferentes! 14 — completar em ordem crescente Para dar uma descricao geral do processo, diremos que uma sutpermutagao de 1. .n € qualquer permutacao de uma subsequéncia de 1..n. Em outras palavras, uma subpermutacdo de 1. .n é qualquer vetor perm[1. .k] cujos elementos pertencem a 1. .n¢ sao diferentes entre si, Agora, 0 algoritmo pode ser organizado de modo que cada iteracdo comece com + uma subpermutacdo pern[1..k] + um candidato m para a posicéo perm[k+1 ] Cada iteracdo incorpora m (aumentando k) ou desiste de m, reduz k, e escolhe um novo m. (Esse movimento de volta, que desfaz o tiltimo elemento de pern|1. .k] ¢ prepara o valor seguinte de m, 6 conhecido como backtrack.) Ao cabo de algumas iteragGes, teremos a sucessora imediata da permutacao inicial ou constataremos que nao existe sucessora, pois a permutagdo inicial ja € a diltima, Segue um esbogo do c6digo que realiza a tarefa. Se k movimento possivel é um backtrack: | ja temos uma permutacdo completa e portanto 0 nico peralk] + 2; Kk: Sek = n) ( imprime (perm, n); m= neds > while (m <= n && Ipode (perm, k, m)) if (men) { peragked] = nets tek ) else ( Af (k <2) breaks m = perm[k] + 15 is y t Free (perm); > static bool pode (int sperm, int k, int m) { for (int d= 4; 1 ce ks +44) if (m == perali]) return false; return trues y Nao € necessrio comecar a primeira iteragao com a permutagdo 1. .n. Podemos comecar com a subpermutacao vazia: basta trocar "for (k= 13 k =) ( «+. A cada passagem por esse ponto, temos um indice k que pertence a 8. .n, um ntimero m que pertence a 1. .n#1, e uma subpermutagio pern[1. .k] de 1. .n com a seguinte propriedade: todas as permutaces lexicograficamente menores que perm[1..k]m jé foram impressas. (A expressao pern[1. .k]m representa a sequéncia x[1. .k+1] tal que x[1.-k] ¢ igual a perm[1. .k] e x[k+1] ==, Essa sequéncia ndo é, necessariamente, uma subpermutacao.) A funcao permutacoes 56 pode ser usada para valores muito modestos de n, uma vez que o ntimero de permutagdes cresce assustadoramente a medida que n aumenta. 1. Prove que ha exatamente n!_ permutagSes de 1... 2. Dwnontante, Verifique, cuidadosamente, a correcio do cédigo de permutacoes nos casos em que n vale@, Le 2. 3. Escreva uma funcio que receba uma permutacio perm[1..n] de 1. .n imprima sua sucessora imediata, 4, VexsAo RECURSIVA. Analise a seguinte verso da funcao permutacoes, que enumera as permutacdes 1, .nem ordem lexicografica, (© que faz, exatamente, a fungdo recursiva permsConPrefixo? vote permutacoes (int n) { int *perns perm = malloc ((ntd) * sizeof (ant); erasComPrefixo (perm, ®, n)s ‘free (perm); y Static void perasConPrefixo (int* sp, int £, int a) { Af (1 >=) imprine (sp, 1); else ¢ for (int m= 15 m c= m5 mex) ( AF (pode (sp, 1, #)) ¢ spliea] = a5 conprefixo (sp, et, m)5)) } > Static bool pode (int “sp, int £, int m) { for (int = 1; k <= 4 kee) AF (m == sp{k]) return false: return trues » 5. UM aLconrtMo cLAssico, Analise o seguinte algoritmo classico de enumeracéo de permuta funcdo recursiva permsConPrefixo? AAs permutacdes so impressas em ordem lexicoge ssde 4. .n. O que faz, exatamente, a void permutacoes (int n) { int *perns ere = malloc ((n+1) * sizeof (int)); For (int = 1; 1 <= nj is) pera[i] = 45 perasconPrefixe (perm, @, n)5 Free (perm); Static void perssconPrefixo (int *pers, int {, int a) { Af (L >= nel) Lnprine (perm, 9); else ( for (int j = iets 9 <= m5 54) ¢ ‘troca (perm, 41, J)5 permsconPretixo (perm, i+1, 1); 5 ‘troca (perm, 42, 3); ) ) Static void troca (int *perm, int ky int 3) ¢ int t= perm[k]; pera{k] = peral}; pera(j] » 6, PeRMUTAGAO DE CADEIAS DE CARACTERES. Escreva uma fungao que imprima todas as permutacdes dos bytes de uma cadeia de caracteres ASCII dada, Por exemplo, ao receber a cadeia ABC, a funcao deve imprimir ABC ACB BAC BCA CBA CB 7. Phostems pas aaisias. & possivelcolocar 8 rainhas do jogo de xadrez sobre o tabuleiro de modo que nenhuma das rainhas possa disposigao das rainhas pode ser representada por um vetor perm. tal que a rainha da linha i fica na coluna peri. (Sugesto: ‘Adapte 0 codigo da funao penmutacoes.) leiro generalizado nxn. Uma 8, Passtio no cavato. Suponha dado um tabuleiro de xadrez n-por-n.. Determine se € posstvel que um cavalo do jogo de xadrez parta da posicio (1,1) do tabuleiro e complete um passeio por todas as n*n posigdes do tabuleiro em m*n ~ 1 passos validos. Por exemplo, para um tabuleiro 5-por-5 uma solucio do problema é sstio: Numere as casas do tabuleiro da maneira ébvia: a primeira linha da esquerda para a direita, depois a segunda linha, etc Agora examine todas as permutacées de 1 2... n?. Para cada permutacio, verifique se ela representa um passeio valido.) 9, Preneuracho caRcULAR, Uma sequéncia s{1 ..1] & permutagio circular de outra t[L..n] se existe k tal que s{k..n] € igual a f{1..n-K+1] es{1..A-1] 6igual a f{u-K+2...n]. Escreva uma fungdo que decida se s[1.. n] & permutagao circular de t[1.. 10. Perwutacko ALEATORA. Escreva uma fungdo que produza uma permutagdo aleatéria de 1... A fungdo deve produzir, com igual probabilidade, qualquer uma das n! permutagdes de 1... Distanc KENDALL. Como medir a distancia entre duas permutacoes’ ‘eja exercicio no capitulo do algoritmo Mergesort. 2 Drsareanjos, Um Meant (= derangement) da sequéncia 1..n é qualquer permutagio dessa sequéncia que muda todos os termos de posicao. Em outras palavras, um desarranjo de 1. .n é qualquer permutacio p[1. .n] de 1. .m tal que pl] € diferente de 4 para todo 4. Por exemplo, 089 desarranjos de 1234 sso 2143, 2341, 2413, 3142, 3412, 3421, 4123, 4312, 4321. Fscreva uma fungao que imprima, exatamente uma vez, cada desarranjo de 1. -n 3, Paxrigoss, Escreva uma funcio que imprima uma lista de todas as particSes do conjunto (1,2, ...,n} em m blocos no vazi pode represent articao por um vetor w[] ..1] com valores em 1. .m dotado da seguinte propriedade: para cada ie 1. existe j tal que wl ‘Atualizado em 2018-0819 https / www imesusp.br/~pt/algoritmos/ Paulo Fey? BCC IME-USP

Você também pode gostar