problema da mochila

Upload: arantes-neylton

Post on 11-Jul-2015

394 views

Category:

Documents


0 download

TRANSCRIPT

Universidade Federal de Minas Gerais Instituto de Cincias Exatas Departamento de Cincia da Computao

PROJETO E ANLISE DE ALGORITMOS Trabalho: disponvel em: http://www.dcc.ufmg.br/ ruiter/paatp2

Ruiter Braga Caldas Professor - Nivio Ziviani

Belo Horizonte 10 de maio de 2004

Sumrio1 O Problema da Mochila1.1 1.2 1.3 Provar que o Problema da Mochila NP-Completo . . . . . . . . . . Mostrar que o Problema est em NP . . . . . . . . . . . . . . . . . . Reduo Polinomial . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1

2 2 2

2 Soluo usando Backtracking 3 Soluo usando Programao Dinmica 4 Soluo usando o Mtodo Guloso 5 Comparao entre os Mtodos5.1

4 6 10 11

Resposta para os Conjuntos de Dados . . . . . . . . . . . . . . . . . . 13

6 Estruturas de Dados A Cdigo Fonte B Tabelas com tempos de execuoB.1 Mtodo Guloso . . . B.1.1 Conjunto I . . B.1.2 Conjunto II . B.1.3 Conjunto III . B.1.4 Conjunto IV . B.2 Mtodo Dinmico . . B.2.1 Conjunto I . . B.2.2 Conjunto II . B.2.3 Conjunto III . B.2.4 Conjunto IV . B.3 Mtodo Backtracking B.3.1 Conjunto I . . B.3.2 Conjunto II . B.3.3 Conjunto III . B.3.4 Conjunto IV . C.1 C.2 C.3 C.4 Conjunto Conjunto Conjunto Conjunto I I I I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

15 19 2727 27 28 29 30 31 31 33 34 35 36 36 37 38 39

C Tabelas com Utilidade Acumulada

3939 41 42 43

2

1 O Problema da MochilaO problema da Mochila (knapsack problem ) pode ser enunciado da seguinte forma: Dados um nmero m 0, um inteiro positivo n e, para cada i em {1, . . . , n}, um nmero vi 0 e um nmero wi 0, encontrar um subconjunto S de {1, . . . , n} que maximize v(S) sob a restrio w(S) m. Onde, v(S) denota a soma iS vi e, analogamente, w(S) denota a soma iS wi . Os nmeros vi e wi podem ser interpretados como utilidade e peso respectivamente de um objeto i. O nmero m pode ser interpretado como a capacidade de uma mochila, ou seja, o peso mximo que a mochila comporta. O objetivo do problema ento encontrar uma coleo de objetos, a mais valiosa possvel, que respeite a capacidade da mochila. Este problema vem sendo estudado deste o trabalho de D.G. Dantzig[5], devido a sua utilizao imediata na Indstria e na Gerencia Financeira, porm foi mais enunciado por razes tericas, uma vez que este freqentemente ocorre pela relaxao de vrios problemas de programao inteira. Toda a famlia de Problemas da Mochila requer que um subconjunto de tens sejam escolhidos, de tal forma que o somatrio das suas utilidades seja maximizado sem exceder a capacidade da mochila. Diferentes tipos de problemas da Mochila ocorrem dependendo da distribuio de tens e Mochilas como citado em [5]: No problema da Mochila 0/1 (0/1 Knapsack Problem ), cada tem pode ser escolhido no mximo uma vez, enquanto que no problema da Mochila Limitado (Bounded Knapsack Problem ) temos uma quantidade limitada para cada tipo de tem. O problema da Mochila com Mltipla Escolha (Multiple-choice Knapsack Problem ) ocorre quando os tens devem ser escolhidos de classes disjuntas, e se vrias Mochilas so preenchidas simultaneamente temos o problema da Mochila Mltiplo (Multiple Knapsack Problem ). A forma mais geral o problema da Mochila com multirestries (Multi-constrained Knapsack Problem ) o qual basicamente um problema de Programao Inteira Geral com Coecientes Positivos. Todos os problemas da Mochila pertencem a famlia NP-Hard [5], signicando que muito improvvel que possamos desenvolver algoritmos polinomiais para este problema. Porm, a despeito do tempo para o pior caso de todos os algoritmos terem tempo exponencial, diversos exemplos de grandes instncias podem ser resolvidos de maneira tima em frao de segundos. Estes resultados surpreendentes vem de vrias dcadas de pesquisa que tem exposto as propriedades estruturais especiais do Problema da Mochila, que tornam o problema to relativamente fcil de resolver. Neste trabalho todos os algoritmos apresentados resolvem o Problema da Mochila 0/1, que consiste em escolher n tens, tais que o somatrio das utilidades maximizado sem que o somatrio dos pesos extrapolem a capacidade da Mochila. Isto pode ser formulado como o seguinte problema de maximizar :n

M aximizarj=1 n

uj x j

Sujeitoj=1

pj xj M

xj {0, 1}, j = 1 . . . n1

onde xj uma varivel binria igual a 1 se j deve ser includo na mochila e 0 caso contrrio.

1.1 Provar que o Problema da Mochila NP-CompletoPara provar que um problema acordo com [6], que: pertence a N P -Completo necessrio provar, de

o mesmo pertence a classe N P , apresentando em algoritmo no-determinista em tempo polinomial ou mostrando que uma dada soluo pode ser vericada em tempo polinomial. Apresentar um reduo em tempo polinomial de um problema N P -completo para o mesmo.

1.2 Mostrar que o Problema est em NPPara provar que o Problema da Mochila 0/1 pertence a classe N P vamos apresentar um algoritmo no-determinista que resolva o problema em tempo polinomial.KnapsackND(cM, uM, n, P [1..n], U [1..n], X[1..n])

1 2 3 4 5 6

for i 1ton do

if ( n P [i] X[i] > cM )OR( 1 then return Insucesso else return Sucesso

X[i] escolhe(0, 1);

n 1

U [i] X[i] < uM )

O procedimento KnapsackN D uma algoritmo No-Determinista para o problema de deciso da Mochila. As linhas de 1-3 atribui o valor 0/1 para o vetor soluo X[i], 0 i n. Na linha 4 feito um teste para vericar se a atribuio do pesos vivel e no ultrapassa a capacidade da Mochila cM e se o resultado da Utilidade pelo menos uM . Uma soluo com sucesso encontrada se as restries so satisfeitas. A complexidade de tempo deste procedimento O(n). Se m o tamanho da entrada usando uma representao binria, o tempo O(m)[4].

1.3 Reduo PolinomialVamos apresentar uma reduo polinomial a partir de outro problema conhecido como NP -Completo para o problema da Mochila. Antes de faz-lo vamos dar uma verso de um problema de deciso para o Problema da Mochila 0/1. O problema de Otimizao difere do problema de Deciso somente na funo de Otimizao. Assim a verso de Deciso para o problema da Mochila a seguinte: Entrada: um conjunto de n tens, tal que todo i tem utilidade ci e peso wi , uma mochila tem capacidade W e um valor positivo C . Questo: Existe um subconjunto S {1, ..., n} de tens, tais que o peso total no mximo W : wi WiS

2

e o valor da utilidade total pelo menos C :

c(S) =iS

ci C?

Para provar que a verso de deciso do problema da Mochila N P -completo vamos fazer uma reduo polinomial a partir do problema Maximum Subset Sum Soluo: A verso do problema de deciso para Maximum Subset Sum denida como apresentada em [3]: Entrada: Um conjunto nito A, um tamanho inteiro positivo si para cada elemento i A, e um inteiro positivo B . Questo: Existe uma subconjunto A A tal que

si = B?iA

Como podemos notar, Maximum Subset Sum um caso especial do problema de Otimizao do Problema da Mochila 0/1 com ci = wi , como citado em [2]. A reduo completa como se apresenta a seguir: Dados uma instncia do problema Subset Sum, reduziremos esta para uma instncia do Problema da Mochila 0/1 da seguinte forma :

U = A, wi = ci = si , W = C = BEsta reduo feita em tempo polinomial, desde que todas as atribuies so executadas em tempo polinomial. Desta forma uma, resposta para uma instncia do problema da Mochila corresponde a uma resposta para o problema Maximum Subset Sum.

Uma resposta "sim"para uma instncia do Problema da Mochila 0/1 signica que existe um subconjunto S U tal que wi W andiS iS

ci C

Isto signica, usando a nossa transformao, que existe um subconjunto A A tal que B si B.iA

Isto ,

si = B.iA

Assim, por denio, uma resposta "sim"para problema Subset Sum.

Um resposta "No"para o Problema da Mochila 0/1, signica que tal conjunto no existe. O que , exatamente, uma resposta negativa para o problema Subset Sum.Assim mostramos que:

o problema da Mochila est em N P e, existe uma reduo polinomial a partir do problema Maximum Subset Sum para o Problema da Mochila 0/1.Com isso provamos que Problema da Mochila 0/1 N P -Completo. 3

2 Soluo usando BacktrackingBacktracking uma estratgia para sistematicamente examinar a lista de possveis solues. A idia do backtracking eliminar a vericao explcita de uma boa parte dos possveis candidatos. Para tanto, o problema deve respeitar as restries que maximizam/minimizam alguma funo de otimizao. Os seguintes passos so respeitados: 1. Denir um espao de soluo para o problema. Este espao de soluo deve incluir pelo menos uma soluo tima para o problema. 2. Organizar o espao de soluo de forma que seja facilmente pesquisado. A organizao tpica uma rvore. 3. Proceder a busca em profundidade. Backtracking uma estratgia que se aplica em problemas cuja soluo pode ser denida a partir de uma seqncia de n decises, que podem ser modeladas por uma rvore que representa todas as possveis seqncias de deciso. De fato, se existir mais de uma disponvel para cada uma das n decises, a busca exaustiva da rvore exponencial. A ecincia desta estratgia depende da possibilidade de limitar a busca, ou seja, podar a rvore, eliminando as sub-rvores que no levam a nenhuma soluo. As solues so representadas por n-tuplas ou vetores de soluo (v1 , v2 , . . . , vn ). Cada vi escolhido a partir de um conjunto nito de opes Si . O algoritmo inicia com um vetor vazio e em cada etapa o vetor extendido com um novo valor formando um novo vetor que pode representar uma soluo parcial do problema. Na avaliao de um vetor (v1 , . . . , vi ), se for constatado que ele no pode representar uma soluo parcial, o algoritmo faz o backtracking, eliminando o ltimo valor do vetor, e continua tentando extender o vetor com outros valores alternativos. Implementamos o algoritmo descrito em [4], este problema possui espao de soluo consistindo de 2n maneiras distintas de atribuir zero ou um para o vetor de soluo X . Este algoritmo faz uso de uma funo limite para ajudar a eliminar alguns ns sem fazer a expanso deles. Uma boa funo limite para este problema obtida usando um limite superior com o valor da melhor soluo vivel obtida pela expanso de um n ativo e qualquer dos seus descendentes. Se este limite superior no for maior que valor da melhor soluo encontrada at o momento, ento este n pode ser eliminado. A funo limite funciona da seguinte forma: Se num n Z qualquer, o valor de xi ,1 i k j foi determinado, ento um limite superior para Z pode ser obtido pela relaxao do requisito de xi = 0 ou xi = 1 por 0 xi 1 para os ns k + 1 i n e usando um algoritmo guloso para resolver o problema da relaxao. A funo Limite determina um limite superior sobre a melhor soluo obtida pela expanso de um n Z no nvel k + 1 do espao de estados.

4

Limite(ut, pt, k, M )

1 2 3 4 5 6 7 8 9

b ut c pt for i k + 1 to n

do

c c + P (i) if c < M then b b + U (i) else return (b + (1 (c M )/P (i)) U (i)) return b

O algoritmo seguinte implementa o mtodo de Backtracking:Metodo_Backtracking(M, n, P, I, pf, if, X)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

pc ic 0 k1 if 1 while 1 = 1

do

pc pc + P (k) ic ic + I(k) Y (k) 1 k k+1 if k > n then if ic pf pc kn XY else Y (k) 0 while Limite(ic, pc, k, M ) if

while (k n)&(pc + P (k) M ) do

do

while (k = 0)&(Y (k) = 1) do if k = 0 then returnk k1

Y (k) 0 pc pc P (k) ic ic I(k) k k+1

O ordem de complexidade de espao para este algoritmo O(2n ) de acordo com [4]. Da funo Limite segue que o limite para um n lho esquerda vivel de um n Z o mesmo para Z . Ento a funo Limite no precisa ser usada sempre que o algoritmo faz um movimento para o lho a esquerda de um n. Desde que o algoritmo tentar fazer um movimento para a esquerda sempre que houver uma 5

escolha entre esquerda e direita, a funo Limite ser chamada somente depois de uma srie de movimento com sucesso para os lhos a esquerda. Quando if = 1, X(i), 1 i n tal que n I(i)X(i) = if . No while nas linhas 6 a 11 movimentos i=1 sucessivos so feitos para lhos a esquerda vivel. Y (i) = 1, 1 i n o caminho para o n corrente. pc = k1 P (i)Y (i) e ic = k1 I(i)Y (i). Se na linha 12, k > n i=1 i=1 ento ic > if indicando que o caminho para esta folha terminou na ltima vez que a funo Limite foi usada. Se k n ento P (i) no cabe e um movimento para um lho direita deve ser feito. Ento Y (k) marcado como 0 na linha 17. Se na linha 18, Limite n, ento o caminho corrente terminou e ele no pode levar a uma soluo melhor que a encontrada at o momento. Nas linhas 20 a 22, retornamos ao longo do caminho para o n mais recente a partir do qual um movimento no tentado pode ser feito. Se no existe este caminho ento o algoritmo termina na linha 23-24. Caso contrrio Y (k), pc e ic so apropriadamente atualizados para corresponder a um movimento para a direita. O limite para este novo n calculado. O processo de retorno das linhas 18 a 27 continua at que um movimento feito para um lho a direita a partir do qual exista uma possibilidade de obter uma soluo com valor maior que if . Considerando o seguinte exemplo para o problema da Mochila: A n U P 1 11 1 2 21 11 3 31 21 4 33 23 5 43 33 6 53 43 7 55 45 8 65 55

Figura 1: Exemplo para o Backtracking rvore mostra as vrias escolhas que so feitas para o vetor de soluo parcial Y . O i-simo nvel da rvore corresponde a uma atribuio 0 ou 1 para Y (i), quando inclui ou exclui o Peso P (i). Os dois nmeros no n so o peso corrente (pc ) e a importncia corrente (ic ). O ns que no contem nmeros tem peso e utilidade idntico aos pais. O nmero de fora do n a direita o limite do n. O limite dos ns a esquerda so os mesmos dos pais. A varivel if do algoritmo atualizada em cada n A, B, C e D. Cada vez que if atualizada, o vetor soluo nal X tambm atualizado. Ao terminar if = 159 e X=(1,1,1,0,1,1,0,0). Dos 29 1 = 511 ns do espao de estados da rvore somente 33 so gerados.

3 Soluo usando Programao DinmicaUma soluo tima baseada no mtodo guloso denida por uma seqncia de decises locais timas, como pode ser visto na prxima seo. Quando o mtodo guloso no funciona, uma possvel sada seria a gerao de todas as possveis seqncias de decises. E a melhor seqncia seria ento escolhida, como no caso do Backtracking acima. Essa soluo de ordem exponencial e, portanto, ineciente. Programao dinmica uma tcnica que tem como objetivo diminuir o nmero de seqncias geradas. A programao dinmica trata o nmero de combinaes da seguinte forma: Vamos considerar n tens, dentre os quais devemos escolher r. Para escolher os r tens, podemos proceder de duas formas: 1. Escolher o primeiro tem. Escolher depois r 1 tens dos n 1 tens restantes. 6

Figura 2: rvore gerada pelo Algoritmo Guloso 2. No escolher o primeiro tem. Ento devemos escolher r tens dos n 1 tens restantesn Est soluo pode ser traduzida da seguinte forma: n = n1 + r1 Se usarmos r r1 uma estratgia de diviso e conquista para implementar esta soluo obteremos um algoritmo com complexidade O(2n ), sendo o maior problema desta abordagem o nmero de vezes que o mesmo problema resolvido. Uma outra abordagem seria usar uma tabela para armazenar as solues que vo se repetir, e essa a idia principal da programao dinmica. Usando esta abordagem para o problema podemos melhor a complexidade deste problema para O(n2 ). Sendo o projeto de uma algoritmo baseado em Programao Dinmica dividido em duas partes:

1. Identicao

determinar uma soluo por diviso e conquista. Analisar e vericar que o tempo de execuo exponencial. Mesmo sub-problema resolvido vrias vezes.2. Construo

Pegar a parte do algoritmo de diviso e conquista que corresponde parte da conquista e substituir as chamadas recursivas por uma olhada na tabela. Em vez de retornar um valor, armazen-lo na tabela. Usar o caso base do algoritmo de diviso e conquista para inicializar a tabela. Determinar o padro de preenchimento da tabela. Denir um lao que utiliza o padro para preencher os demais valores da tabela.7

Figura 3: Instncia para o Algoritmo de Programao Dinmica Vamos apresentar um exemplo do problema da Mochila onde a utilizao da programao dinmica permite encontrar a soluo tima. Sejam n tens de tamanhos s1, s2, . . . , sn, conforme a Figura 3. A idia vericar se existe um subconjunto desses tens cujo tamanho total seja exatamente S . Numa soluo por diviso e conquista, devemos ter problemas menores da mesma natureza. Podemos Generalizar para a situao em que temos i tens e o tamanho total j . Para saber se retornamos verdadeiro, temos que analisar duas possibilidades: 1. O i-simo tem usado para completar o tamanho j . 2. O i-simo item no usado e, portanto j alcanado at os i 1 primeiros tens. Devemos usar uma tabela t[n, S] para armazenar t, caso seja possvel completar S com os n elementos. Caso no seja possvel, preenchemos com f . Pelo denido acima uma clula t[i, j] deve ser preenchida com t se uma das duas situaes verdadeira:t[i 1, j si ] ou T [i 1, j]. O padro de preenchimento seria ento o mesmo apresentado na Figura 4

Figura 4: Padro de preenchimento da tabela Sendo assim a tabela nal teria o formato da Figura 5: O algoritmo utilizado na implementao foi extrado de:

http://www.mpi-sb.mpg.de/ rybal/armc-live-termin/node5.html http://www-cse.uta.edu/ holder/courses/cse2320/lectures/l15/node12.html http://www.cse.uni.edu/ goddard/Courses/CSCE310J

8

Figura 5: Formato Final da TabelaMetodo_Dinmico(v[1..n], w[1..n], n, W )

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

c[0, w] 0 for i 1 to n

for w 0 to W do

do do

c[i, 0] = 0 for i 1 to n

for w 1 to W do if w[i] w then if v[i] + c[i 1, w w[i]] > c[i 1, w] then

c[i, w] = v[i] + c[i 1, w w[i]] else c[i, w] = c[i 1, w] else c[i, w] = c[i 1, w]

Podemos deduzir a complexidade deste algoritmo atravs da manipulao que executada em cada lao, sendo que os dois laos iniciais so apenas para inicializar a tabela, sendo o lao da linha 1 a 3 da ordem O(W ), onde W a capacidade da Mochila, e o lao da linha 4 a 6 da ordem O(n), onde n o nmero de tens. Os laos seguintes realizam a construo da tabela, o lao da linha 7 a 17 executa O(n) e o lao da linha 9 a 17 executa O(W ) vezes, sendo este algoritmo da ordem de O(n W ). O algoritmo acima encontra apena o maior valor possvel que pode ser alocado na Mochila, para saber quais os tens que tornam este valor mximo outro algoritmo foi implementado:

9

Backtrace(n, W )

1 2 3 4 5 6 7 8 9

in jM while ((i > 0)&(j > 0)) do if (c[i, j] c[i 1, j]) then X[i] 1 j j w[i] i else X[i] 0 i

4 Soluo usando o Mtodo GulosoO mtodo Guloso a tcnica de projeto mais simples que pode ser aplicada a uma grande variedade de problemas. A grande maioria destes problemas possui n entradas e requerido obter um subconjunto que satisfaa alguma restrio. Qualquer subconjunto que satisfaa esta restrio chamado de soluo vivel. Queremos ento encontrar uma soluo vivel que maximize ou minimize uma dada funo objetivo. Uma soluo vivel que satisfaa a funo objetivo chamada de soluo tima. Existem maneiras bvias de determinar uma soluo vivel, mas no necessariamente uma soluo tima[4]. O mtodo Guloso sugere que podemos construir uma algoritmo que trabalhe em estgios, considerando uma entrada por vez. Em cada estgio, uma deciso tomada considerando se uma entrada particular uma soluo tima. Isto conseguido considerando as entradas numa ordem determinada por algum processo de seleo. Se a incluso da prxima entrada na soluo tima construda parcialmente resultar numa soluo invivel, ento esta entrada no ser adicionada a soluo parcial. O processo de seleo em si baseada em alguma medida de otimizao. Esta medida pode ou no ser a funo objetivo. Na verdade vrias medidas de otimizao diferentes podem aplicveis para um determinado problema. Muitas destas, entretanto, resultaro em algoritmos que geraro soluo sub-timas. O algoritmo escolhido para esta implementao usa a estratgias gulosas mais interessante, de acordo com [4], este estratgia faz uma negociao entre a taxa em que a utilidade decresce e o peso usado. Em cada passo ser includo um objeto que tem a maior utilidade pro unidade de peso usado. Isto signica que o objeto ser considerado na ordem decrescente da Maior Utilidade sobre o Peso (U (i)/P (i)). Se os objetos estiverem ordenado numa ordem decrescente de Utilidade sobre o Peso (U (i)/P (i) U (i + 1)/P (i + 1)) o algoritmo abaixo, extraido de [4] e adaptado a partir da linha 9 a 13 para resolver o problema da Mochila 0/1, resolve o problema da Mochila usando a estratgia gulosa. Sem considerar o tempo de ordenao da entrada, que na implementao foi usado o algoritmo do quicksort extrado do livro [6], o algoritmo abaixo executa a estratgia gulosa em tempo O(N ). Esse algoritmo realiza os seguintes passos:

o vetor soluo X inicializado; a capacidade utilizada da mochila armazenado em cum;10

O primeiro lao F OR, da linha 3 a 8, colocando cada tem na mochila, subtraindo o peso do tem do valor de cum. Isso feito at que a cum no comporte o prximo peso. Neste ponto todos os tem de maior relao U (i)/P (i) foram colocado na Mochila. O segundo lao F OR, da linha 9 a 13, muda de estratgia e procura nos tens restantes aquele(s) que possua um peso que caiba no valor restante de cum para preencher o espao da Mochila.Metodo_Guloso(U [1..n], P [1..n], M, n)

1 2 3 4 5 6 7 8 9 10 11 12 13

do

X0 cum M for i 1 to n

X(i) 1; cum cum P (i) for j i to n

if P (i) > cum then Exit;

do

if P (j) A[*j].Chave) (*j)--; if (*i