Técnicas de Divisão e Conquista e de Programação Dinâmica para a resolução de Problemas de Otimização

Francisco Vando Carneiro Moreira Gerardo Valdisio Rodrigues Viana Faculdade Lourenço Filho Universidade Estadual do Ceará Resumo
Encontrar o valor máximo ou mínimo de uma função é um problema bastante utilizado em diversas áreas. Em geral, este valor é chamado de "ótimo" pois corresponde ao melhor dentre todos os possíveis num espaço de soluções viáveis. Neste contexto define-se a otimização, que pode ser restrita, quando a solução atender determinadas condições impostas pelo problema, ou irrestrita, quando qualquer solução dentro do domínio da função é investigada. Classificam-se como problemas mais difíceis aqueles em que o espaço de soluções não é contínuo, caracterizando a chamada Otimização Discreta, ou Combinatória, definida assim: “dado um conjunto A de elementos, deseja-se encontrar um subconjunto S ⊆ A tal que a função objetivo, aplicada aos elementos de S, possui o valor "ótimo" que pode ser de máximo (maior de todos) ou de mínimo (menor de todos)”. Como o número de opções para a escolha de S cresce de forma exponencial com o tamanho do conjunto A, métodos exatos para obter a "solução ótima" precisam percorrer todo o espaço, o que se torna impraticável. Para isto existem os métodos aproximados que correspondem às heurísticas, meta-heurísticas e algoritmos aproximativos. Dentre estes, destacam-se as técnicas de Divisão e Conquista e de Programação Dinâmica. Neste trabalho, mostramos o funcionamento destes dois algoritmos aplicados a alguns problemas conhecidos de otimização combinatória.

Palavras-chave: Divisão e Conquista, Programação Dinâmica, Algoritmos, Problema da Mochila.

1. INTRODUÇÃO
Dados, uma “mochila” com capacidade C e um conjunto A com n itens, onde cada item i ∈ A contém um peso Pi > 0 e uma utilidade, ou valor, Vi > 0, deseja-se determinar um subconjunto S ⊆ A tal que a soma dos pesos dos elementos de S não ultrapasse a capacidade da mochila e a soma dos respectivos valores seja a maior possível. Este artigo apresenta duas soluções com paradigmas distintos para este clássico problema de otimização combinatória. O primeiro algoritmo utiliza a estratégia de Divisão e Conquista na ordenação dos custos relativos (Peso/Valor) por intercalação (MergeSort). A

6

Revista Científica da Faculdade Lourenço Filho - v.8, n.1, 2011

seguir é utilizada uma heurística gulosa para obter uma solução aproximada. Estando os custos relativos em ordem não decrescente, o funcionamento do algoritmo guloso consiste em aceitar, a cada iteração, o primeiro item que aparecer, verificando a cada passo se a capacidade da mochila é, ou não, ultrapassada. O resultado obtido por esta estratégia é, em geral, próxima da melhor solução possível, ou seja, da solução ótima. O segundo algoritmo utiliza o método da programação dinâmica que sempre encontra a solução ótima, porém, com um tempo proporcional ao “valor” da entrada e não ao seu “tamanho”, como é comum na análise da função de complexidade de um algoritmo. Veremos que, para uma entrada de um dado tamanho n (número de itens) com a capacidade da mochila C, o tempo de execução deste algoritmo poderá ser relativamente grande, portanto, inviável. Deste modo diz-se que o algoritmo de programação dinâmica possui uma complexidade pseudo-polinomial. Nos experimentos computacionais foram consideradas algumas instâncias do problema da Mochila para cada um dos algoritmos implementados. Com os resultados, dispostos numa tabela, é possível comparar a aproximação das soluções e seus respectivos tempos de execução.

2. DIVISÃO E CONQUISTA
O paradigma Divisão e Conquista consiste em dividir o problema a ser resolvido em partes menores, encontrar soluções para as partes, e então combinar as soluções obtidas em uma solução global. ZIVIANI (2007) cita “o uso do paradigma para resolver problemas nos quais os subproblemas são versões menores do problema original geralmente leva a soluções eficientes e elegantes, especialmente quando é utilizado recursivamente”. A Divisão e Conquista emprega modularização de programas e frequentemente conduz a um algoritmo simples e eficiente. Esta técnica é bastante utilizada em desenvolvimento de algoritmos paralelos, onde os subproblemas são tipicamente independentes um dos outros, podendo assim serem resolvidos separadamente.

Menor distância entre pontos.1.8. Ordenação rápida (quicksort) e por intercalação (mergesort). • • Conquista: resolver cada subproblema recursivamente. 2.Revista Científica da Faculdade Lourenço Filho . Tamanho da pilha (número de chamadas recursivas e/ou armazenadas pode causar estouro de memória). conforme a indicada na Figura 1. Combinação: combinar as soluções encontradas em cada subproblema. É de fácil implementação. a técnica de Divisão e Conquista consistem em 3 passos: • Divisão: dividir a instância do problema original em duas ou mais instâncias menores. compondo uma solução para o problema original. 2. . Sua representação pode ser feita através de uma árvore binária.2 Desvantagens • • • Necessidade de memória auxiliar.1 Vantagens • • • Indicado para aplicações que tem restrição de tempo. Simplifica problemas complexos. 2. Pesquisa em árvore binária.v.3 Algumas aplicações • • • • Multiplicação de inteiros longos. considerando-as como subproblemas. Repetição de Subproblemas. Um exemplo para ilustrar o uso dessa técnica é o algoritmo de ordenação de um vetor por intercalação (MergeSort). n. 2011 7 Segundo FIGUEIREDO (2011).

Este algoritmo. usa o procedimento de intercalação (Merge) entre dois conjuntos previamente ordenados.8. apresentado na Figura 2. Cada um destes vetores menores é ordenado recursivamente utilizando o mesmo procedimento. conclui-se então que a complexidade do algoritmo no pior caso é O(n log n) (VIANA e CINTRA. . 2011) A altura (h) da árvore de execução é O (log n) e a quantidade de operações em cada nível da árvore é assintoticamente igual a O(n). 2011 Figura 1 – Técnica de Divisão e Conquista Fonte: MergeSort (FIGUEIREDO.8 Revista Científica da Faculdade Lourenço Filho . n. O MergeSort garante que os dois subproblemas têm tamanho da ordem de n/2. um deles terá um elemento a mais que o outro). 2011).1.v. mas requer alocação de memória para o vetor temporário de tamanho n. O MergeSort (ordenação por intercalação) divide o vetor de entrada em dois outros vetores com metade do tamanho do vetor original (em caso de tamanho ímpar.

. meio.meio] = primeira série ordenada // L[meio+1. ini. meio. meio) se (meio + 1) < fim MERGESORT(L. 2011 9 Algoritmo MERGESORT (L. fim) f i m {MERGESORT} Figura 2 – Algoritmo para o MergeSort Fonte: Viana e Cintra (2011. PROCEDIMENTO MERGE ( L. p. k = 1..v. Vetor L[ini. meio. fim) ENTRADA: um vetor L e as posições ini e fim SAÍDA: o vetor L em ordem crescente da posição ini até a posição fim inicio se ini < fim meio = (ini + fim)/2 // divisão inteira se ini < meio MERGESORT(L. ini.fim] // L[ini. 30) A Figura 3 mostra o algoritmo MERGE que faz a intercalação entre as duas partes de L. j = meio + 1 enquanto ( i ≤ meio e j ≤ fim ) se ( L[i] ≤ L[j]) S[k] = L[i] i = i + 1 senão S[k] = L[j] j = j + 1 k = k + 1 // fim se // fim enquanto 〈〈〈 continua 〉〉〉 .fim] = série intercalada /ordenada inicio i = ini..8.fim] = segunda série ordenada SAÍDA: Registro L com uma única série ordenada // L[ini..1.Revista Científica da Faculdade Lourenço Filho . ini. fim) MERGE(L. fim. meio + 1. ini. n. fim ) ENTRADA: inteiros: ini.

A técnica de Divisão e Conquista foi utilizada como um procedimento auxiliar para esta classificação. Observa-se. 2011 se ( i > meio ) p = j q = fim senão p = i q = meio para i = p até q S[k] = L[i] k = k + 1 // fim para L[ini. acima abordado.fim] = S[1.(fim-ini+1)] retorna (L) f i m {MERGE} Figura 3 – Algoritmo de Intercalação Fonte: Viana e Cintra (2011) 3. onde se tem a estratégia gulosa baseado no custo relativo através da ordenação MergeSort do paradigma de divisão e conquista. A ordenação inicial refere-se à ordem não decrescente do chamado custo relativo (Peso/Valor). que foram unidas as duas técnicas. Este objeto escolhido passa a fazer parte da solução construída até então.8. A descrição do algoritmo é feita a seguir.. Em cada passo (iteração) do algoritmo é selecionado ou escolhido o primeiro elemento do conjunto ordenado que “caiba” na mochila. n.1.10 Revista Científica da Faculdade Lourenço Filho . neste contexto. .v. resultando em um algoritmo. ALGORITMO GULOSO PARA O PROBLEMA DA MOCHILA Para resolver o problema da Mochila booleana (0/1) de forma aproximada foi utilizada uma heurística gulosa apresentada na Figura 4..

. seguindo o “princípio de otimalidade de Bellman” (DIAS et al. ou seja.1. X[j].v.. n ) para i = 1 até n e enquanto C ≠ 0 j = C / P[i] // divisão inteira X[i] = min { j . aqui cada subproblema é dependente de pelo menos um outro.n ) f i m {MOCHILA_0/1_Guloso} Figura 4 – Algoritmo para o Problema da Mochila Fonte: Campello e Maculan (1994) 4. diferentemente da técnica de divisão e conquista. uma solução parcial obtida somente é calculada uma única vez.n] vetor com os pesos dos itens SAÍDA: X[1.n] vetor com os valores(custos) dos itens e P[1. 2011 11 Algoritmo MOCHILA_0/1_Guloso ENTRADA: C= capacidade da Mochila.Revista Científica da Faculdade Lourenço Filho . Na Programação Dinâmica resolvem-se os problemas de pequena dimensão e guardam-se as soluções em tabelas dinâmicas.8.n] vetor binário que indica se o item i é selecionado(1) ou não (0) Sol = solução (valor máximo da Função objetivo) Inicio Sol = 0 para i = 1 até n L[i] = V[i] / P[i] // fim para MERGESORT ( L. A solução final é obtida combinando as soluções dos problemas menores . PROGRAMAÇÃO DINÂMICA A Programação Dinâmica (PD) pode ser caracterizada como um processo sequencial de tomada de decisões. 1 } C = C – X[i]*P[i] Sol = Sol + X[i]*V[i] // fim para escreve ( Sol. n = número de itens V[1. onde uma decisão ótima global pode ser obtida através da otimização de subproblemas (ou ótimos locais) individuais. 2010).. 1. a fim de evitar redundância de cálculo. n. j=1. Este procedimento é importante porque..

a complexidade continua exponencial. os algoritmos desenvolvidos por programação dinâmica é polinomial. 2011 (ROSA.8. ou seja. como no caso do problema do caixeiro viajante. reduzindo drasticamente o tempo de execução. então. 2011). A idéia básica da programação dinâmica sugere. Pode-se dizer que a Programação Dinâmica é uma maneira esperta de transformar recursão em iteração. somente soluções ótimas dos subproblemas podem compor uma solução ótima do problema original (RIBEIRO.1. uma estrutura geral para algoritmos projetados conforme Figura 5.12 Revista Científica da Faculdade Lourenço Filho .v. 1999). Outras vezes. mas de ordem mais baixa. Aplica-se quando uma estratégia ótima para resolver um problema continua a ser ótima quando este é subproblema de um problema maior.Estrutura Geral da Programação Dinâmica Fonte: Munari e Augusto (2007) . Figura 5 . e da partição. daí ser chamada de Otimização Recursiva. Muitas vezes quando o algoritmo direto tem complexidade exponencial. n.

Por exemplo. ( ( A x B ) x C ) x D c. teríamos as seguintes possibilidades de realizar o produto. até que as partes atingem o tamanho da entrada original. ( A x ( B x C ) ) x D Figura 6 – Possibilidades do produto de 4 matrizes. p. a entrada é decomposta em partes mínimas para as quais são obtidas respostas diretas. conforme colocação de parênteses que indicam a prioridade indicada em cada uma das árvores da Figura 6.1. Os nós intermediários contém os resultados parciais e a raiz. Quando então sua solução é recuperada e o processo finalizado. Esta ordem de execução do produto de duas matrizes acarreta valores distintos do número de multiplicações total e o que se deseja é minimizar este valor: a... Um exemplo clássico para a aplicação desta técnica é a ordem de produto de matrizes. Onde cada Ai é uma matriz com mi-1 linhas e mi colunas. n. o produto AxBxCxD Fonte: Dasgupta et al (2008. 2011 13 Na inicialização. citado em (ZIVIANI. A 2 = B ( 2 0 x 1 ) .Revista Científica da Faculdade Lourenço Filho . a cada iteração vai aumentando tamanho das partes e obtendo respostas correspondentes a partir das já geradas. A x ( ( B x C ) x D ) b.8. A ordem na qual as matrizes são multiplicadas pode ter um efeito enorme no número total de operações de adição e multiplicação necessárias para obter M.v. que ilustra bem a técnica de programação dinâmica por meio de determinar a melhor forma de avaliar o produto de várias matrizes: M = A1 x A2 x. ( A x B ) x ( C x D ) d. A 3 = C ( 1 x 1 0 ) e A 4 = D ( 1 0 x 1 0 0 ) . se A1=A ( 5 0 x 2 0 ) . x An. 170) . A x ( B x ( C x D ) ) e. 2007).

10 + 50 . .v. . ( m 1 x m 2 ) . Parentetização a) A ( ( B C ) D) b) ( ( A B ) C ) D c) ( A B ) ( C D ) d) A ( B ( C D ) ) e) ( A ( B C ) ) D No de multiplicações necessárias para o produto 20 . . 20 .r) multiplicações para obter Z ( p x r ) = X Y . 20 . 20 . C e D. ( m n . 10 . m1. 100 + 50 . . 100 + 50 .8. m2 = 1. 1 . .Ak . seriam necessárias 120200 multiplicações. Na Tabela 1 é mostrado o custo total de cada alternativa que corresponde ao total de multiplicações requeridas em cada caso. . . 100 20 . .1 x m n ) . . 20 . sabemos que o produto das matrizes X ( p x q ) por Y ( q x r ) existe e requer (p. 1 + 50 . 20 . 10 .14 Revista Científica da Faculdade Lourenço Filho .mn-1. conforme mostra a Tabela 2.1. Este valor é aproximadamente a mesma relação entre os tempos de execução do algoritmo. 2011 Considerando X ( p x q ) uma matriz com p linhas e q colunas. .mk. 1 . 100 50 . 10 + 20 . neste exemplo. n. . m3 = 10 e m4 = 100 para definir as ordens das n=4 matrizes A. . . B. 100 50 . 10 .q. . 10 . 1 + 1 . 100 Custo total 120200 51050 7000 103000 60200 Tabela 1 – Escolha do melhor arranjo (c) para o produto de 4 matrizes Observa-se. 1 . 100 + 50 . que para o pior arranjo. 1 . 100 + 20 . m1 = 20. Para o exemplo anterior teríamos m0 = 50. 100 1 . A instância {m0. 10 + 50 . 10 + 50 . O total P(n) de maneiras distintas para colocação de parênteses numa sequência de n matrizes é dada pela seguinte forma recursiva: P(n) cresce de forma exponencial em função de n. A2. . 1 . 10 .. An com respectivas ordens ( m 0 x m 1 ) . mn) representa a sequência do produto das matrizes A1. .. isto equivale a mais de 17 vezes o melhor arranjo (7000 multiplicações).

..n terá estrutura ótima.8.. Usando a tabela dinâmica contendo valores de multiplicações escalares para calcular a matriz Ai. n.n = (A1. 2011 15 n 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 P(n) 1 1 2 5 14 42 132 429 1430 4862 16796 58786 208012 742900 2674440 n 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 P(n) 9694845 ≈ 107 35357670 ≈ 108 129644790 ≈ 109 477638700 ≈ 109 1767263190 ≈ 1010 6564120420 ≈ 1010 24466267020 ≈ 1011 91482563640 ≈ 1011 343059613650 ≈ 1012 1289904147324 ≈ 1013 4861946401452 ≈ 1013 18367353072152 ≈ 1014 69533550916004 ≈ 1014 263747951750360 ≈ 1015 1002242216651368 ≈ 1016 Tabela 2 – Número de alternativas para colocação de parênteses entre n matrizes O uso da Programação Dinâmica para o problema do produto de matrizes tem por objetivo encontrar uma estrutura de parentetização ótima sem ter que gerar todas estas possibilidades.. j mais o A definição recursiva para o custo mínimo de colocar parênteses no produto Ai.i = Ai e representa o menor custo para calcular Ai..j = Ai Ai+1 .k e Ak+1.. podemos observar que A1..n tem estruturas ótimas (ou sub-ótimas) podemos afirmar que A1. Considerando a notação para definir a cadeia Ai.Revista Científica da Faculdade Lourenço Filho .1... .v.n).k) x (Ak+1. temos não há nenhum cálculo e custo para multiplicar estas duas matrizes. Pelo princípio da otimalidade da PD.j é: . se as subcadeias A1.j então.k e Ak+1 ... Aj indicativa do produto da sequência de matrizes Ai até Aj. .. ou seja: como mínimos pois Ai.

j] é mínimo.v.j] = k return M[1. i. j ] + 1.k] + M[k+1. S f i m {PD_Produto_Matrizes} Figura 7 – Algoritmo para resolver o Problema do Produto de várias matrizes por Programação Dinâmica Procedimento PRINT_CADEIA ( S. S[ i . 2011 Para armazenarmento da solução ótima. j ) inicio se i = j print “A” senão print “(” PRINT_CADEIA ( S. i.n] .1.i]=0 para L= 2 até n para i= 1 até n-L+1 j = i + L – 1 M[i. j ] ) PRINT_CADEIA ( S. pode-se utilizar uma matriz S.j] = q S[i. Os algoritmos apresentados nas figuras 7 e 8 resolvem o problema do produto de matrizes. Algoritmo PD_Produto_Matrizes ENTRADA: um vetor P contendo as ordens das n matrizes SAÍDA: matrizes M e S contendo a solução inicio para i =1 até n M[i.16 Revista Científica da Faculdade Lourenço Filho . tal que o valor de S[i.8.j] contém o valor de k tal que M[i. S[ i . j ) print “)” f i m { PRINT_CADEIA } Figura 8 – Gera a cadeia de caracteres referente à saída do algoritmo da Figura 7 . n.j] M[i.j] + P[i]*P[k]*P[j] se q < M[i.j] = ∞ para k= i até j-1 q = M[i.

Figura 9 – Resultado do Programa do Anexo A.2. Útil para aplicar em problemas que exigem teste de todas as possibilidades.8. obtendo os seguintes resultados mostrados a seguir na Figura 9.Revista Científica da Faculdade Lourenço Filho . 2011 17 Os programas implementados em C# correspondentes aos algoritmos das Figuras 7 e 8 estão representados no Anexo A. .1 Vantagens da Programação Dinâmica • • • Pode ser utilizada num grande número de problemas de otimização discreta. Como exemplo de seu funcionamento foi executado o programa para uma dada instância.2 4. n.1.v. Não necessita de muita precisão numérica.

18 Revista Científica da Faculdade Lourenço Filho .n] vetor com os pesos dos itens SAÍDA: X[1.n] vetor binário que indica se o item i é selecionado(1) ou não (0) Sol = solução (valor máximo da Função objetivo) ...3 Algumas aplicações • • Multiplicação de várias matrizes Projeto de sistemas confiáveis 5. n = número de itens V[1.v. PROBLEMA DA MOCHILA POR PROGRAMAÇÃO DINÂMICA Conforme definido anteriormente. 2011 4.1. Como o problema é de maximização a definição recursiva para a programação dinâmica é específica para este problema é dada por: O algoritmo a seguir resolve o problema: Algoritmo MOCHILA_0/1_PD ENTRADA: C= capacidade da Mochila. n. uma instância do Problema da Mochila booleana é definida por um conjunto com n itens com seus pesos Pi e valores Vi para uma mochila de capacidade C.8.2 Desvantagens • • Necessita de grande espaço de memória A complexidade espacial pode ser exponencial 4.n] vetor com os valores(custos) dos itens e P[1..

k] = aux k = k− 1 / / fim se j = j− 1 / / fim enquanto fim { Mochila_0/1_PD } Figura 10 – Algoritmo para o Problema da Mochila por Programação Dinâmica .j− 1] . j− 1] + V[j] / / fim para Sol = M[C. 2011 19 inicio para i = 1 até C M[i.j−1] X[j] = 1 aux = aux − V[j] k = j− 1 enquanto M[C.1.n] / / rotina para determinar o vetor X (itens selecionados) aux = Sol j = n enquanto j > 0 se M[C. M[i− P[j] .j− 1] senão M[i.v.k] > aux M[c.0] = 0 para j = 1 até n M[0.j] = max ( M[i.j] = M[i.8.Revista Científica da Faculdade Lourenço Filho .j] ≠ M[c.j] = 0 X[j] = 0 para i = 1 até C se P[j] > i M[i. n.

Ótima Conhecida 1 2 3 4 5 6 7 8 KP4 KP100000 KP1000 KP2500 KP5000 KP7500 KP10000 KP20000 4 4 1000 2500 5000 7500 10000 20000 10 100000 500 295 2500 3804 5000 10000 70 70 1280 8560 37660 58165 77621 *** 0 0. Para efeito de comparação para o problema da mochila. A elaboração deste programa tem como objetivo ser de uso acadêmico. n.0 Asp.NET 4.125 2. foram utilizadas oito instâncias distintas. Cada instância descrita em um arquivo de texto representa uma mochila com sua capacidade e seus itens identificados nas primeiras colunas da Tabela 3. bem como a solução encontrada.Net MVC utilizando a IDE Visual Studio 2010 Ultimate.718 6. processador Intel Core 2 Duo e sistema operacional Microsoft Windows XP.250 11.1.484 - 70 70 1280 8560 37859 58164 77621 153576 0 0 0.046 0. resolvido tanto pela técnica de Divisão e Conquista como por Programação Dinâmica. Foi desenvolvida uma ferramenta em C#.8. As demais colunas da Tabela 3 apresenta estes resultados.718 6.171 0.484 - 70 70 12800 8560 37660 58260 77621 254921 Tabela 3 – Resultados obtidos para algumas instâncias do Problema da Mochila . A avaliação das instâncias foi realizada em uma máquina com 2 GB de Ram. EXPERIMENTOS COMPUTACIONAIS Na abordagem utilizada para avaliar a aplicação de Técnicas de Divisão e Conquista e Programação Dinâmica para o problema da mochila.171 0.250 11. Nº Instância Nº Itens Capacidade Sol_1(PD) Tempo_1 Sol_2(DC) Tempo_2 Sol. 2011 6. retornamos o tempo gasto por cada técnica.20 Revista Científica da Faculdade Lourenço Filho .v.125 2.

001s e se o conteúdo for “***” indica que houve um estouro da pilha de execução. Comparando as técnicas de Divisão e Conquista e Programação Dinâmica percebe-se que no caso da instância com maior número de itens houve o estouro de recursos computacionais. sugerindo que a técnica deve ser utilizada de forma controlada. the most difficult problems are those in which the solution set is not continuous. As the number of options for selecting S grows exponentially with the size of the set A. exact methods to obtain the "optimal solution" must search in the all space. Algorithm. we show the performance of these two algorithms applied to some known combinatorial optimization problems. Quando informados igual a “0” representam um tempo menor que 0. which can be restricted when the solution satisfy the conditions imposed by the problem.8. Among these. 2011 21 Após execução do programa descrito no Anexo A. n. Knapsack Problem. metaheuristics and approximation algorithms. Among these. Dynamic Programming. In general. defined as follows: “Given a set A of elements and we want to find a subset S ⊆ A such that the objective function applied to elements of S has the optimal value that can be maximum (greatest) or minimum (less of all).Revista Científica da Faculdade Lourenço Filho . In this paper. there are the techniques of divide and conquer and dynamic programming. characterizing the so-called discrete or combinatorial optimization.1. CONCLUSÃO Os resultados mostraram que a eficiência das técnicas e o tempo e recursos demandados estão intrinsecamente relacionados aos parâmetros de configuração de entrada. Keywords: Divide-and-Conquer. 7. . Divide-and-Conquer and Dynamic Programming Technical for solving Optimization Problems Abstract Find the maximum or minimum of a function is a problem widely used in various areas.v. or unrestricted when any solution within domain of the function is investigated. In this context it’s defined the optimization. this is called "optimal value" because it corresponds to the best of all possible within a feasible solution space. which becomes impractical.4 apresentamos os resultados com os valores de tempo expressos em segundos. For this there are approximate methods that correspond to heuristics.

V. Notas de Aula. Algorithms.com . RIBEIRO. C. Desenvolvimento e Avaliação de Performance. FIGUEIREDO. Pesquisa e Ordenação de Dados. “Paradigmas de Resolução de Problemas. DASGUPTA. (1994).E.R. MUNARI Júnior e AUGUSTO.1. SOARES.. Paradigmas e Técnicas de Projeto de Algoritmos.A.F.. C. Instituto de Informática da UFRGS.dsc. VIANA. (2007). (2007). FEUP ROSA. DIAS. Universidade Federal de Campina Grande.. Disponível em: http://www. Licenciatura em Engenharia Informática e Computação..Instituto de Ciência Matemática e Computação.A. TOSCANI. 2011 Referências CAMPELLO. J. Utilização do Algoritmo de Fechos Convexos na Programação Dinâmica Estocástica: Simpósio Brasileiro de Sistemas Elétricos. J. S. ZIVIANI. Porto Alegre: Sagra Luzzatto. T. (2011). L. Editora da Universidade Federal Fluminense.22 Revista Científica da Faculdade Lourenço Filho . BRANDI. Francisco Vando Carneiro Moreira Graduado em Ciência da Computação – FLF Mestrando Acadêmico em Ciência da Computação – MACC/UECE e-mail: fvando@gmail. Programação Dinâmica. OLIVEIRA. “Projeto e Algoritmos com implementações em Pascal e C”. G. E. R. Complexidade de Algoritmos. P. (2010). Notas de aula da disciplina Algoritmos e Estruturas de Dados II. e CINTRA. (1999). I.br/~abrantes/CursosAnteriores/ATAL051/DivConq. e VELOSO. MARCATO. e RAMOS. N. (2011) Programação Dinâmica. “Divisão e Conquista.edu.S. McGraw-Hill Higher Education.ufcg. and VAZIRANI. B..pdf. Algoritmos e Heurísticas. n. São Paulo: Editora Thomson. e MACULAN. G. Notas de Aula da disciplina Analise e Técnicas de Algoritmo” .v. P. R. A. (2002). (2011). N.. Fortaleza: Publicação do Sistema UAB/UECE. ICMC/USP. SILVA. PAPADIMITRIOU. S. Slides”. Universidade de São Paulo .8. U. Niterói-RJ. (2008).

8.v. 2011 23 Gerardo Valdisio Rodrigues Viana Bacharel em Engenharia Mecânica – UFC Licenciado em Matemática – UFC Doutor em Ciência da Computação – UFC/USP e-mail: valdisio. n.viana@uece.br .1.Revista Científica da Faculdade Lourenço Filho .

peso)) <= (Convert. List<Mitem> sorted = new List<Mitem>(a. right = MergeSortDefault(right). } else if (leftptr == left.v.peso)))) { sorted.peso))))) { sorted.Count).Count) && (Convert.1 – Programa em C# para o Problema da Mochila 0/1 – utiliza a Técnica de Divisão e Conquista para a ordenação e um Algoritmo Guloso para selecionar os itens .ToDecimal(right[rightptr]. for (int i = 0. n. for (int i = 0.ToDecimal(right[rightptr].Count . i < a.Count || ((rightptr < right.Count/2.1.24 Revista Científica da Faculdade Lourenço Filho .Add(a[i + middle]). int leftptr = 0. List<Mitem> right = new List<Mitem>(a.ToDecimal(left[leftptr].ToDecimal(left[leftptr].Count == 1) return a.Add(right[rightptr]). 2011 ANEXOS public List<Mitem> MergeSortDefault(List<Mitem> a) { if (a. } } return sorted. left = MergeSortDefault(left).Add(left[leftptr]). List<Mitem> left = new List<Mitem>(middle).middle.Add(a[i]). for (int k = 0.Count || ((leftptr < left. int rightptr = 0. leftptr++. k < a. i++) right.Count .middle). int middle = a. i++) left. rightptr++. ListaNew = new List<Mitem>(a. } } A. i < middle.Count.8.Count) && ((Convert.peso)) <= (Convert. k++) { if (rightptr == right.Count).

int j = 0.1]) * int. n).Add(M). i++) m[i.Parse(p[j]).Parse(p[k]) * int. for (i = 1. ArrayList S = new ArrayList(). j). k++) { q = m[i. int[. j] = q. s[i.Add(resultadoSolution). return RetornoGeral. if (q < m[i.8. int num) { int q = 0. } } } printSolutionParentheses(s.1. i] = 0. j] + int.] m = new int[sz. i . int l = 0. int k = 0.2 – Programa em C# para o Problema do Produto de Matrizes – utiliza a Técnica de Programação Dinâmica para minimizar o número de multiplicações . RetornoGeral. S. int[. ArrayList M = new ArrayList(). 2011 25 public List<ArrayList> Ordem_Multiplicacao_Matriz(string[] p. i++) { j = i + l . n. sz]. i <= n.1. for (l = 2.Add(resultadoMatrizM).Add(S). s. j]) { m[i. k <= j .1. j] = k. M. for (k = i. i <= (n . } } A. List<ArrayList> RetornoGeral = new List<ArrayList>().v. l++) for (i = 1.1. RetornoGeral. j] = INF. sz].] s = new int[sz.Parse(p[i . int i = 0. l <= n. k] + m[k + 1. int n = num. printm(m.Revista Científica da Faculdade Lourenço Filho .l + 1). m[i.

v.3 – Tela do programa para o problema do Produto de Matrizes .1.8.26 Revista Científica da Faculdade Lourenço Filho . 2011 A. n.

1].8.valor)) { dp[k. i < D.obj[i].Count]. i] = 1.Revista Científica da Faculdade Lourenço Filho .] dp = new int[C + 1. i . d[k.1] > (dp[k .Length.valor.peso) { dp[k. i . ii]. i] = 0. i++) { for (int k = 0.Count . i] = dp[k . k <= C. while (ii >= 0) { D[ii] = d[k1. k <= C.Mitem> MochilaProgramacaoDinamica(int C.1].Count. i] = dp[k. List<Mitem> obj) int[. ii--. i] = 0.x = D[i]. obj. d[k.valor. for (int k = 0. k++) if (k < obj[0].1. } else { dp[k.peso * D[ii]). } A.obj[i].1] + obj[i]. i] = dp[k. int[. i++) obj[i]. i .1] + obj[i].peso.peso) { dp[k. i .Count]. } for (int i = 0.Count].4 – Programa em C# para o Problema da Mochila por Programação Dinâmica .peso. d[k. } { for (int i = 1. int ii = obj. 0] = obj[0]. 0] = 0. i < obj. } else { if (dp[k. int[] D = new int[obj. k1 -= (obj[ii]. n. k++) { if (k < obj[i]. 2011 27 public List<ClassDC. d[k. obj.v. 0] = 1. return obj. d[k. } } } } int k1 = C. i . } else { dp[k.] d = new int[C + 1.1. 0] = 0.

Sign up to vote on this title
UsefulNot useful