• Nenhum resultado encontrado

Um estudo algorítmico para a otimização de compra em grupo com múltiplos fornecedores e descontos em escala

N/A
N/A
Protected

Academic year: 2021

Share "Um estudo algorítmico para a otimização de compra em grupo com múltiplos fornecedores e descontos em escala"

Copied!
146
0
0

Texto

(1)

DEPARTAMENTO DE INFORMÁTICA E MATEMÁTICA APLICADA

BACHARELADO EM CIÊNCIA DA COMPUTAÇÃO

Um estudo algorítmico para a otimização de

compra em grupo com múltiplos

fornecedores e descontos em escala

Vinícius Araújo Petch

Natal-RN Junho de 2016

(2)

Um estudo algorítmico para a otimização de

compra em grupo com múltiplos fornecedores e

descontos em escala

Monografia de Graduação apresentada ao Departamento de Informática e Matemática Aplicada do Centro de Ciências Exatas e da Terra da Universidade Federal do Rio Grande do Norte como requisito parcial para a obtenção do grau de bacharel em Ciência da Computação.

Orientador

Prof. Dr. Marco César Goldbarg

Universidade Federal do Rio Grande do Norte – UFRN Departamento de Informática e Matemática Aplicada – DIMAp

Natal-RN Junho de 2016

(3)

escala apresentada por Vinícius Araújo Petch e aceita pelo Departamento de Informática e Matemática Aplicada do Centro de Ciências Exatas e da Terra da Universidade Federal do Rio Grande do Norte, sendo aprovada por todos os membros da banca examinadora abaixo especificada:

(4)
(5)

Agradecimentos

Agradeço a todos da minha família, que acreditaram em mim e me acompanharam durante esta jornada.

Agradeço a todos os meus professores, que me ensinaram e me ajudaram a chegar até aqui. Em especial, agradeço ao meu orientador, que me auxiliou com o seu conhecimento, e me conduziu neste trabalho com a sua paciência e experiência.

Agradeço não só a todos que estudaram comigo, mas também a todos que eu conheci durante o curso, que passaram por diversos momentos comigo, tornando a minha experiência neste curso algo único.

(6)

Comandar muitos é o mesmo que comandar poucos. Tudo é uma questão de organização. Sun Tzu

(7)

Um estudo algorítmico para a otimização de

compra em grupo com múltiplos fornecedores e

descontos em escala

Autor: Vinícius Araújo Petch Orientador(a): Prof. Dr. Marco César Goldbarg

R

ESUMO

Este trabalho estuda a otimização na distribuição de compradores em um grupo de fornecedores, levando em consideração as necessidades e preferências baseadas nas características do produto, os descontos em grupo disponibilizados pelos fornecedores e a disponibilidade do produto no estoque dos fornecedores. Este estudo é composto da contextualização e definição formal do problema, definição dos algoritmos e cálculos utilizados, criação de instâncias, experimentos computacionais e análise dos resultados. Os algoritmos implementados e testados a partir de experimentos computacionais são os algoritmos branch-and-bound, Hill climbing, algoritmo genético, algoritmo memético, Variable Neighborhood Search (VNS) e Greedy Randomized Adaptive Search (GRASP), além dos algoritmos, funções e heurísticas criadas especificamente para este problema.

Palavras-chave: Otimização Combinatória, Algoritmos Metaheurísticos, Estudo Algorítmico.

(8)

An algorithmic study for the optimization of group

purchase with multiple suppliers and discounts in

scale

Author: Vinícius Araújo Petch Advisor: Prof. Dr. Marco César Goldbarg

A

BSTRACT

This work studies the optimization in the distribution of buyers in a group of suppliers, taking into consideration the necessities and preferences based on the product’s characteristics, group discounts available by the suppliers and the availability of the product on the suppliers’ stock. This study is composed of contextualization and formal definition of the problem, definition of the utilized algorithms and calculations, creation of instances, computational experiments, and analysis of results. The algorithms implemented and tested by computational experiments are the branch-and-bound, hill climbing, genetic algorithm, memetic algorithm, Variable Neighborhood Search (VNS), Greedy Randomized Adaptive Search (GRASP), and also algorithms, functions and heuristics created specifically for this problem.

Keywords: Combinatory Optimization, Metaheuristics Algorithms, Algorithmic Study.

(9)

Lista de algoritmos

Algoritmo 1. Pseudocódigo do algoritmo de cálculo de função de potencial de

escopo local ... 35

Algoritmo 2. Pseudocódigo do algoritmo de cálculo de função de potencial de escopo semi-global ... 36

Algoritmo 3. Pseudocódigo do algoritmo de cálculo de função de potencial de escopo global ... 36

Algoritmo 4. Pseudocódigo da implementação do algoritmo branch-and-bound. O limite superior inicial deve ser encontrado por meio de outro algoritmo ... 41

Algoritmo 5. Pseudocódigo do algoritmo de limite inferior por multiplicação ... 41

Algoritmo 6. Pseudocódigo do algoritmo de limite inferior por abstração ... 42

Algoritmo 7. Algoritmo da heurística construtiva totalmente aleatória (hc-ta) ... 44

Algoritmo 8. Algoritmo das heurísticas construtivas por função de potencial de escopo local fpel), escopo semi-global fpesg) e escopo global (hc-fpeg). A função 𝑐𝑎𝑙𝑐𝑢𝑙𝑎𝑟𝑃𝑜𝑡𝑒𝑛𝑐𝑖𝑎𝑙(𝑖, 𝑐𝑜𝑚𝑝𝑟𝑉𝑖𝑛𝑐[𝑖]) é escolhida a partir de uma das funções de cálculo de potencial descritas na seção 3.1 ... 44

Algoritmo 9. Algoritmo da busca local de transferência (ls-transfer) ... 45

Algoritmo 10. Algoritmo da busca local de troca simples (ls-swap-s) ... 47

Algoritmo 11. Algoritmo da busca local de troca persistente (ls-swap-p) ... 48

Algoritmo 12. Algoritmo da busca local de melhor opção (ls-swap-mo) ... 48

Algoritmo 13. Algoritmo da busca local de patamar (ls-level) ... 51

Algoritmo 14. Algoritmo de escolha do fornecedor fonte por roleta ponderada ... 53

(10)

Algoritmo 15. Algoritmo de escolha do fornecedor destino por roleta ponderada ... 54 Algoritmo 16. Pseudocódigo da implementação do algoritmo hill climbing. A função ℎ𝑒𝑢𝑟𝐶𝑜𝑛𝑠𝑡𝑟() é um dos algoritmos de heurística construtiva descritos na seção 3.3. A função 𝑏𝑢𝑠𝑐𝑎𝐿𝑜𝑐𝑎𝑙() uma das buscas locais descritas na seção 3.4 ... 55 Algoritmo 17. Pseudocódigo da implementação do algoritmo genético. A função ℎ𝑒𝑢𝑟𝐶𝑜𝑛𝑠𝑡𝑟() é um dos algoritmos de heurística construtiva descritos na seção 3.3. A função 𝑐𝑟𝑜𝑠𝑠𝐴𝑙𝑔() é um dos algoritmos de cruzamento descritos nesta seção. ... 57 Algoritmo 18. Pseudocódigo do algoritmo de cruzamento n-ponto (c-np) ... 59 Algoritmo 19. Pseudocódigo do algoritmo de cruzamento totalmente aleatório (c-ta) ... 60 Algoritmo 20. Pseudocódigo do algoritmo de cruzamento aleatório equilibrado (c-ae) ... 60 Algoritmo 21. Pseudocódigo do algoritmo de cruzamento por função de potencial. A função 𝑐𝑎𝑙𝑐𝑢𝑙𝑎𝑟𝑃𝑜𝑡𝑒𝑛𝑐𝑖𝑎𝑙(𝑖, 𝑐𝑜𝑚𝑝𝑟𝑉𝑖𝑛𝑐𝑖) é escolhida a partir de uma das funções de cálculo de potencial descritas na seção 3.1 ... 61 Algoritmo 22. Pseudocódigo da implementação do algoritmo memético. A função ℎ𝑒𝑢𝑟𝐶𝑜𝑛𝑠𝑡𝑟() é um dos algoritmos de heurística construtiva descritos na seção 3.3. A função 𝑐𝑟𝑜𝑠𝑠𝐴𝑙𝑔() é um dos algoritmos de cruzamento descritos na seção 3.6. A função 𝑏𝑢𝑠𝑐𝑎𝐿𝑜𝑐𝑎𝑙() é uma das buscas locais descritas na seção 3.4 ... 63 Algoritmo 23. Pseudocódigo da implementação do algoritmo VNS. A função ℎ𝑒𝑢𝑟𝐶𝑜𝑛𝑠𝑡𝑟() é um dos algoritmos de heurística construtiva descritos na seção 3.3. A funções 𝑙𝑠𝐿𝑒𝑣𝑒𝑙() e 𝑙𝑠𝑇𝑟𝑎𝑛𝑠𝑓𝑒𝑟() são descritas seção 3.4. A função 𝑙𝑠𝑆𝑤𝑎𝑝() é uma das buscas locais de troca descritas na seção 3.4.1. ... 66 Algoritmo 24. Pseudocódigo da implementação do algoritmo path relinking. Os parâmetros necessários pela busca local de patamar foram abstraídos. A

(11)

função ℎ𝑒𝑢𝑟𝐶𝑜𝑛𝑠𝑡𝑟() é um dos algoritmos de heurística construtiva descritos na seção 3.3. A funções 𝑙𝑠𝐿𝑒𝑣𝑒𝑙() e 𝑙𝑠𝑇𝑟𝑎𝑛𝑠𝑓𝑒𝑟() são descritas seção 3.4. A função 𝑙𝑠𝑆𝑤𝑎𝑝() é uma das buscas locais de troca descritas na seção 3.4.1. A função 𝑝𝑎𝑡ℎ𝑅𝑒𝑙𝑖𝑛𝑘𝑖𝑛𝑔() é descrita nessa seção ... 68 Algoritmo 25. Pseudocódigo da implementação do path relinking ... 70

(12)

Lista de ilustrações

Figura 1. Comparação da média dos resultados dos algoritmos para o grupo de instâncias 10a ... 124 Figura 2. Comparação da média dos resultados dos algoritmos para o grupo de instâncias 10b ... 125 Figura 3. Comparação da média dos resultados dos algoritmos para o grupo de instâncias 10c ... 126 Figura 4. Comparação da média dos resultados dos algoritmos para o grupo de instâncias 15a ... 127 Figura 5. Comparação da média dos resultados dos algoritmos para o grupo de instâncias 15b ... 128 Figura 6. Comparação da média dos resultados dos algoritmos para o grupo de instâncias 15c ... 129 Figura 7. Comparação da média dos resultados dos algoritmos para o grupo de instâncias 20a ... 130 Figura 8. Comparação da média dos resultados dos algoritmos para o grupo de instâncias 20b ... 131 Figura 9. Comparação da média dos resultados dos algoritmos para o grupo de instâncias 20c ... 132 Figura 10. Comparação da média das médias dos resultados de cada algoritmo, separado por grupo de instâncias, tamanho e classe ... 133 Figura 11. Divisão da quantidade de vezes que cada algoritmo teve a melhor média em cada instância, separado por grupo de instâncias, tamanho e classe ... 135 Figura 12. Divisão da quantidade de vezes que cada heurística construtiva teve a melhor média em cada instância, separado por grupo de instâncias, tamanho e classe ... 135

(13)

Lista de tabelas

Tabela 1. Quantidade de compradores e fornecedores de acordo com o tamanho da instância ... 73 Tabela 2. Quantidade de características, características obrigatórias, características optativas e bônus das características optativas, de acordo com o tamanho da instância ... 74 Tabela 3. Distribuição da capacidade dos fornecedores, em relação à classe e tamanho ... 74 Tabela 4. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-ta para o grupo de instâncias 10a ... 75 Tabela 5. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpel para o grupo de instâncias 10a ... 75 Tabela 6. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpesg para o grupo de instâncias 10a ... 76 Tabela 7. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpeg para o grupo de instâncias 10a ... 76 Tabela 8. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-ta para o grupo de instâncias 10b ... 77 Tabela 9. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpel para o grupo de instâncias 10b ... 77

(14)

Tabela 10. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpesg para o grupo de instâncias 10b ... 78 Tabela 11. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpeg para o grupo de instâncias 10b ... 78 Tabela 12. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-ta para o grupo de instâncias 10c ... 79 Tabela 13. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpel para o grupo de instâncias 10c ... 79 Tabela 14. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpesg para o grupo de instâncias 10c ... 80 Tabela 15. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpeg para o grupo de instâncias 10c ... 81 Tabela 16. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-ta para o grupo de instâncias 15a ... 81 Tabela 17. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpel para o grupo de instâncias 15a ... 82 Tabela 18. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpesg para o grupo de instâncias 15a ... 82 Tabela 19. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpeg para o grupo de instâncias 15a ... 83

(15)

Tabela 20. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-ta para o grupo de instâncias 15b ... 83 Tabela 21. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpel para o grupo de instâncias 15b ... 84 Tabela 22. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpesg para o grupo de instâncias 15b ... 84 Tabela 23. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpeg para o grupo de instâncias 15b ... 85 Tabela 24. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-ta para o grupo de instâncias 15c ... 85 Tabela 25. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpel para o grupo de instâncias 15c ... 86 Tabela 26. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpesg para o grupo de instâncias 15c ... 86 Tabela 27. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpeg para o grupo de instâncias 15c ... 87 Tabela 28. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-ta para o grupo de instâncias 20a ... 87 Tabela 29. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpel para o grupo de instâncias 20a ... 88

(16)

Tabela 30. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpesg para o grupo de instâncias 20a ... 89 Tabela 31. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpeg para o grupo de instâncias 20a ... 89 Tabela 32. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-ta para o grupo de instâncias 20b ... 90 Tabela 33. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpel para o grupo de instâncias 20b ... 90 Tabela 34. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpesg para o grupo de instâncias 20b ... 91 Tabela 35. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpeg para o grupo de instâncias 20b ... 91 Tabela 36. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-ta para o grupo de instâncias 20c ... 92 Tabela 37. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpel para o grupo de instâncias 20c ... 92 Tabela 38. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpesg para o grupo de instâncias 20c ... 93 Tabela 39. Melhor resultado, pior resultado, média dos resultados, mediana dos resultados, desvio padrão e desvio padrão normalizado da heurística hc-fpeg para o grupo de instâncias 20c ... 93

(17)

Tabela 40. Média do melhor resultado, pior resultado, média dos resultados, mediana e desvio padrão da heurística hc-ta, dividido por grupo de

instâncias, tamanho e classe ... 94

Tabela 41. Média do melhor resultado, pior resultado, média dos resultados, mediana e desvio padrão da heurística hc-fpel, dividido por grupo de instâncias, tamanho e classe ... 94

Tabela 42. Média do melhor resultado, pior resultado, média dos resultados, mediana e desvio padrão da heurística hc-fpesg, dividido por grupo de instâncias, tamanho e classe ... 95

Tabela 43. Média do melhor resultado, pior resultado, média dos resultados, mediana e desvio padrão da heurística hc-fpeg, dividido por grupo de instâncias, tamanho e classe ... 95

Tabela 44. Configuração escolhida pelo irace para o hill climbing ... 96

Tabela 45. Resultados do hill climbing para o grupo de instâncias 10a ... 97

Tabela 46. Resultados do hill climbing para o grupo de instâncias 10b ... 97

Tabela 47. Resultados do hill climbing para o grupo de instâncias 10c ... 97

Tabela 48. Resultados do hill climbing para o grupo de instâncias 15a ... 98

Tabela 49. Resultados do hill climbing para o grupo de instâncias 15b ... 98

Tabela 50. Resultados do hill climbing para o grupo de instâncias 15c ... 98

Tabela 51. Resultados do hill climbing para o grupo de instâncias 20a ... 99

Tabela 52. Resultados do hill climbing para o grupo de instâncias 20b ... 99

Tabela 53. Resultados do hill climbing para o grupo de instâncias 20c ... 100

Tabela 54. Média do melhor resultado, pior resultado, média dos resultados, mediana e desvio padrão do hill climbing, dividido por grupo de instâncias, tamanho e classe ... 100

Tabela 55. Configurações escolhidas pelo irace para o algoritmo genético . 101 Tabela 56. Resultados do algoritmo genético para o grupo de instâncias 10a ... 101

(18)

Tabela 57. Resultados do algoritmo genético para o grupo de instâncias 10b ... 102 Tabela 58. Resultados do algoritmo genético para o grupo de instâncias 10c ... 102 Tabela 59. Resultados do algoritmo genético para o grupo de instâncias 15a ... 102 Tabela 60. Resultados do algoritmo genético para o grupo de instâncias 15b ... 103 Tabela 61. Resultados do algoritmo genético para o grupo de instâncias 15c ... 103 Tabela 62. Resultados do algoritmo genético para o grupo de instâncias 20a ... 104 Tabela 63. Resultados do algoritmo genético para o grupo de instâncias 20b ... 104 Tabela 64. Resultados do algoritmo genético para o grupo de instâncias 20c ... 104 Tabela 65. Média do melhor resultado, pior resultado, média dos resultados, mediana e desvio padrão do algoritmo genético, dividido por grupo de instâncias, tamanho e classe ... 105 Tabela 66. Configurações escolhidas pelo irace para o algoritmo memético ... 106 Tabela 67. Resultados do algoritmo memético para o grupo de instâncias 10a ... 106 Tabela 68. Resultados do algoritmo memético para o grupo de instâncias 10b ... 107 Tabela 69. Resultados do algoritmo memético para o grupo de instâncias 10c ... 107 Tabela 70. Resultados do algoritmo memético para o grupo de instâncias 15a ... 108

(19)

Tabela 71. Resultados do algoritmo memético para o grupo de instâncias

15b ... 108

Tabela 72. Resultados do algoritmo memético para o grupo de instâncias 15c ... 108

Tabela 73. Resultados do algoritmo memético para o grupo de instâncias 20a ... 109

Tabela 74. Resultados do algoritmo memético para o grupo de instâncias 20b ... 109

Tabela 75. Resultados do algoritmo memético para o grupo de instâncias 20c ... 110

Tabela 76. Média do melhor resultado, pior resultado, média dos resultados, mediana e desvio padrão do algoritmo memético, dividido por grupo de instâncias, tamanho e classe ... 110

Tabela 77. Configurações escolhidas pelo irace para o VNS ... 111

Tabela 78. Resultados do VNS para o grupo de instâncias 10a ... 112

Tabela 79. Resultados do VNS para o grupo de instâncias 10b ... 112

Tabela 80. Resultados do VNS para o grupo de instâncias 10c ... 112

Tabela 81. Resultados do VNS para o grupo de instâncias 15a ... 113

Tabela 82. Resultados do VNS para o grupo de instâncias 15b ... 113

Tabela 83. Resultados do VNS para o grupo de instâncias 15c ... 114

Tabela 84. Resultados do VNS para o grupo de instâncias 20a ... 114

Tabela 85. Resultados do VNS para o grupo de instâncias 20b ... 114

Tabela 86. Resultados do VNS para o grupo de instâncias 20c ... 115

Tabela 87. Média do melhor resultado, pior resultado, média dos resultados, mediana e desvio padrão do VNS, dividido por grupo de instâncias, tamanho e classe ... 115

Tabela 88. Configurações escolhidas pelo irace para o GRASP ... 117

(20)

Tabela 90. Resultados do GRASP para o grupo de instâncias 10b ... 117

Tabela 91. Resultados do GRASP para o grupo de instâncias 10c ... 118

Tabela 92. Resultados do GRASP para o grupo de instâncias 15a ... 118

Tabela 93. Resultados do GRASP para o grupo de instâncias 15b ... 119

Tabela 94. Resultados do GRASP para o grupo de instâncias 15c ... 119

Tabela 95. Resultados do GRASP para o grupo de instâncias 20a ... 120

Tabela 96. Resultados do GRASP para o grupo de instâncias 20b ... 120

Tabela 97. Resultados do GRASP para o grupo de instâncias 20c ... 120

Tabela 98. Média do melhor resultado, pior resultado, média dos resultados, mediana e desvio padrão do GRASP, dividido por grupo de instâncias, tamanho e classe ... 121

Tabela 99. Quantidade de vezes que cada heurística construtiva obteve a melhor média em cada instância, separado por grupo de instâncias, tamanho de classe ... 134

Tabela 100. Quantidade de vezes que cada algoritmo, com exceção das heurísticas construtivas, obteve a melhor média em cada instância, separado por grupo de instâncias, tamanho e classe ... 134

(21)

Lista de abreviaturas e siglas

fpel – Função de potencial de escopo local

fpesg – Função de potencial de escopo semi-global fpeg – Função de potencial de escopo global

li-m – Limite inferior por multiplicação li-a – Limite inferior por abstração

hc-ta – Heurística construtiva totalmente aleatória

hc-fpel – Heurística construtiva por função de potencial de escopo local hc-fpesg - Heurística construtiva por função de potencial de escopo semi-global

hc-fpeg - Heurística construtiva por função de potencial de escopo global ls-transfer – Busca local de transferência

ls-swap-s – Busca local de troca simples ls-swap-p – Busca local de troca persistente

ls-swap-mo – Busca local de troca de melhor opção ls-level – Busca local de patamar

e-ta – Método de escolha totalmente aleatório

m-fpel – Método de escolha por melhor potencial de escopo local

m-fpesg – Método de escolha por melhor potencial de escopo semi-global m-fpeg – Método de escolha por melhor potencial de escopo global

r-fpel – Método de escolha por roleta de escopo local

r-fpesg – Método de escolha por roleta de escopo semi-global r-fpeg – Método de escolha por roleta de escopo global

c-np – Cruzamento n-ponto

c-ta – Cruzamento totalmente aleatório c-ae – Cruzamento aleatório equilibrado

c-fpel – Cruzamento por função de potencial de escopo local

c-fpesg – Cruzamento por função de potencial de escopo semi-global c-fpeg – Cruzamento por função de potencial de escopo global

VNS – Variable Neighborhood Search

(22)

Sumário

1 Introdução ...23 2 Descrição do problema ...25 2.1 Importância do tema ... 27 2.2 Dificuldade de solução ... 27 2.3 Formalização do problema ... 28 3 Algoritmos de solução ...33 3.1 Funções de potencial ... 34 3.2 Algoritmo branch-and-bound ... 37 3.2.1 Funcionamento e implementação ... 38 3.3 Heurísticas construtivas ... 43 3.4 Buscas locais ... 45 3.4.1 Buscas locais unitárias ... 45 3.4.2 Buscas locais de patamar ... 49 3.5 Hill climbing ... 54 3.5.1 Funcionamento e implementação ... 54 3.6 Algoritmo genético ... 55 3.6.1 Funcionamento e implementação ... 56 3.7 Algoritmo memético ... 61 3.7.1 Funcionamento e implementação ... 62 3.8 Variable Neighborhood Search ... 64 3.8.1 Funcionamento e implementação ... 65 3.9 GRASP e path relinking ... 67 3.9.1 Funcionamento e implementação ... 68

(23)

4 Experimentos computacionais ...71 4.1 Instâncias utilizadas ... 72 4.2 Heurísticas construtivas ... 74 4.3 Hill climbing ... 96 4.4 Algoritmo genético ... 100 4.5 Algoritmo memético ... 105 4.6 VNS ... 111 4.7 GRASP e path relinking ... 116 4.8 Comparação e análise dos resultados ... 121

5 Conclusões ...137 6 Considerações finais ...140 Referências ...143

(24)

1 Introdução

Hoje em dia, os sistemas de compra on-line são ferramentas intensamente utilizadas em virtude de diversas facilidades oferecidas ao comprador. A aquisição pode ser realizada 24 horas por dia, de forma ubíqua e com várias comodidades de oferta, acesso e de formas de pagamento. Um caso particular e cada vez mais comum de compra é a chamada compra em grupo. Nesse tipo de compra, objetiva-se alcançar descontos em função do número de pessoas do grupo. É usual que o desconto exija um número mínimo de participantes do grupo. Em casos particulares é possível que o fornecedor pratique tarifas diferentes em função da quantidade de indivíduos no grupo. Usualmente em serviços de compra coletiva como Groupon, Peixe Urbano e similares, o desconto é fixo e normalmente muito convidativo, atraindo a formação do grupo de compradores. Todavia existe o risco, sob a ótica do fornecedor, do número de pessoas atraído pelo desconto não atender uma eventual escala mínima para a prática do desconto. Sob a ótica do comprador, não há vantagens adicionais quando o grupo formado supera significativamente o número mínimo de compradores que supostamente está associado ao desconto praticado.

Um problema mais complexo emerge quando o comprador pode aderir a diferentes grupos de compra que oferecem diferentes características e descontos do produto desejado. É possível pensar nesse problema de alocação de clientes à fornecedores sob uma ótica centralizada. Nesse caso o problema de formar grupos de compras passa a ser um problema com dois diferentes tipos de clientes a serem satisfeitos: vendedores e compradores. Na dimensão dos fornecedores o objetivo é maximizar o lucro. Na dimensão dos compradores o objetivo é minimizar a despesa. Para alcançar a melhor política de compra, o comprador individual depende da política de compra dos demais compradores, pois é ela que permite atingir melhores demandas e, consequentemente, melhores descontos. Por outro lado, os fornecedores devem regular sua política de desconto para atrair as maiores demandas.

(25)

Caso o objetivo final seja encontrar um ponto de compromisso entre ganho de compradores e vendedores, como prevê a teoria da oferta e procura em mercados de livre concorrência, a melhor alocação compradores versus fornecedores poderá ser calculada de forma determinística e em função das informações existente no mercado. O presente trabalho encaminha uma solução para alcançar o equilíbrio entre compra e venda minimizando a despesa total dos compradores, todavia atendendo todas as restrições de escala e de desconto sugeridas pelos fornecedores desse mercado. No modelo proposto as características básicas dos produtos são fixadas pelos compradores e atendidas na solução de compra. Fornecedores oferecem seus produtos com as caraterísticas que livremente desejam, na escala de sua política de venda, dentro dos descontos que julgam adequados. Características adicionais dos produtos são listadas pelos compradores e o modelo busca atendê-las se possível e conforme a prioridade e o valor quantificado pelo comprador.

Este trabalho, portanto, tem o objetivo de estudar uma versão mais completa e genérica do problema de compras coletivas on-line, versão em que as informações sobre o processo de compra e venda é perfeitamente conhecido.

O presente trabalho sugere algoritmos que solucionam de forma aproximada o problema de formar grupos de compras que maximizem o desconto alcançado pelo conjunto de compradores (não pelo comprador individual) sobre um conjunto de ofertas de produtos idênticos, mas vendidos por diversos fornecedores que permitem diferentes características e associam diferentes descontos ao tamanho do grupo de compras formado.

O trabalho apresenta experimentos computacionais que objetivam validar o desempenho dos algoritmos desenvolvidos. Ao final são alcançadas conclusões e sugestões para futuros trabalhos.

(26)

2 Descrição do problema

O cenário do problema tratado no presente trabalho envolve, de um lado, um grupo de compradores desejando comprar um certo tipo de produto, e de outro, uma rede de fornecedores. Os compradores e fornecedores tomam suas decisões livremente. Os compradores possuem uma lista de características próprias para o produto que desejam adquirir (chamadas de características obrigatórias), e características que desejam, caso possível, também encontrar no produto se possível (chamadas de características optativas). O comprador só adquire um certo produto caso este possua todas as características obrigatórias de sua lista. As demais características desejáveis são consideradas através de um sistema de bônus associado à presença da caraterística no produto adquirido. Caso uma caraterística optativa esteja presente no produto, o bônus dessa caraterística é somado ao desconto individual do comprador. As características optativas variam de comprador para comprador, todavia o bônus de presença da característica é contabilizado de forma constante, de modo que dependa da mesma e não do comprador.

Por outro lado, o mercado possui um conjunto de fornecedores, cada um vendendo o produto desejado pelo comprador, todavia com características próprias de sua oferta. Características que podem ou não atender às exigências obrigatórias ou optativas de um certo comprador. Para tentar atrair compradores, os fornecedores oferecem descontos no preço do produto aos compradores que o escolherem. Todavia, o desconto está associado à formação de um grupo de compra para aumentar a escala da compra. Pode haver mais de um tipo de desconto em função da escala do grupo de compras formado. Cada desconto depende de uma certa quantidade mínima de compradores. Os descontos são distribuídos de forma não linear em relação à escala do grupo de compras, normalmente em degraus ou patamares. Um patamar é a demanda mínima exigida para que um certo valor de desconto associado seja liberado pelo fornecedor. O

(27)

desconto permanece constante entre a demanda mínima que autoriza um dado valor de desconto e um novo limiar de demanda que autoriza um desconto ainda maior. A partir de um certo valor de demanda sugere-se que o desconto não mais seja alterado, alcançando um valor máximo. Normalmente o limite do último patamar, ou patamar final de desconto, é realizado em função da disponibilidade do produto no fornecedor. Os compradores associados a um certo fornecedor são denominados de compradores vinculados. Caso a quantidade de compradores vinculados a um fornecedor alcance a capacidade do último patamar de desconto, não será mais possível associar compradores a esse fornecedor uma vez que a capacidade do fornecedor estará esgotada.

O objetivo do problema é maximizar a satisfação dos compradores. A satisfação do esquema de compras pode ser entendida como a grandeza obtida pelo somatório de todos os descontos fornecidos aos compradores e pelo acumulado dos bônus alcançados pelo esquema de compra em função das características optativas. Bônus e descontos são somados para representar a satisfação.

Visando utilizar um programa de minimização, escolheu-se minimizar o resultado final da soma dos custos de compra subtraído dos descontos e bônus obtidos. A soma do custo de todos os compradores é representada pelo valor total da compra sem desconto, ou seja, o valor que seria pago pelos compradores em uma situação normal, sem os descontos de escala obtido pela formação de grupos de compras. Desse valor nominal é subtraído o valor total de descontos (calculado em função da formação de grupos de desconto e segundo os patamares de demanda), somado ao valor total de bônus (dados pelas características optativas atendidas).

Para facilitar a formação de instâncias onde os compradores possam comprar seu produto e as perdas decorrentes da insatisfação da frustração de uma compra com desconto possa ser minimizadas ao ponto desse efeito ser desconsiderado, a quantidade de patamares de tarifas de cada fornecedor é a mesma, ou seja, sendo n um inteiro positivo, todos os fornecedores praticarão uma política de venda com n estágios de descontos

(28)

ou patamares (sendo o último patamar o patamar final). Todos os compradores oferecerão o mesmo produto. O produto oferecido por cada fornecedor possuirá características diferentes que poderão ser interpretadas como obrigatórias ou optativas de acordo com cada comprador. Sendo j e k números naturais, todos os compradores exigirão de um produto j características obrigatórias e considerarão positivamente a presença de k características optativas. Por fim, os fornecedores possuem o mesmo preço básico para seu produto, valor p, diferenciando-se pelas tarifas de desconto e quantidade de compradores exigidos nos grupos de compra Consequentemente, considerando que toda a demanda será atendida, sendo x a quantidade de compradores, o preço total sem desconto a ser pago por todos os compradores será 𝑥 ∗ 𝑝.

2.1 Importância do tema

O problema foi inicialmente proposto para a área de e-commerce, trabalhando com venda de vários fornecedores e fabricantes para vários compradores. Esta é uma área que movimenta uma grande quantidade de compradores, o que tornaria o problema proposto plausível e viável. Porém, mesmo tendo sido proposto com essa finalidade, o problema não é limitado à área de e-commerce ou à área de compra e venda. Qualquer problema que relacione elementos a conjuntos e envolva limitações a cada elemento, bônus de acordo com o conjunto, e bônus caso uma quantidade mínima de compradores seja vinculada, pode ser então modelado no problema proposto e então resolvido com os algoritmos que serão estudados aqui.

2.2 Dificuldade de solução

O problema mais próximo ao nosso problema proposto encontrado na literatura foi o Problema da Mochila Múltipla Binária, que pertence à classe de problemas NP-Completos. Este problema trata de distribuir objetos com um valor atribuído, com apenas uma unidade cada, entre múltiplas

(29)

mochilas. As mochilas seriam representadas pelos fornecedores, enquanto os objetos seriam os compradores. O valor atribuído a cada objeto poderia ser representado pelas características optativas. O que torna o problema proposto mais difícil que o problema da mochila é o fato de que o bônus das características optativas variam de fornecedor para fornecedor, e todo o problema relacionado aos patamares, descontos e características obrigatórias não existe no problema da mochila. Por terem essas características adicionais, podemos então assumir que o problema proposto também pertence à classe de problemas NP-Completos.

2.3 Formalização do problema

São dados inicialmente um conjunto de compradores C (2), um conjunto de fornecedores F (3), um conjunto de características Chr (4), o valor do bônus de uma característica optativa bOpt (18) e o custo do produto prodCost (19).

Uma solução S (1) é um conjunto de vínculos vn (9), compostos de um comprador cm (5) e um fornecedor fr (6). Cada comprador é composto de um conjunto de características obrigatórias obg, e um conjunto de características optativas opt. Cada fornecedor é composto de um conjunto de características fChr, um conjunto de limites fLm e um conjunto de descontos fDsc. Para um vínculo ser válido, é necessário que o conjunto obg seja um subconjunto do conjunto fChr (10).

O problema consiste em encontrar a solução S com o menor custo (17) possível. Para calcular o custo de uma solução S, é necessário calcular o custo relativo aos descontos (14) e o custo relativo às características optativas (12). O custo relativo aos descontos é calculado contabilizando quantos compradores estão vinculados a cada fornecedor (16) e, para cada limite inferior à quantidade de compradores, um desconto de mesmo índice é ativado (15). Para cada vínculo, o custo relativo às características optativas é calculado adicionando o bônus das características optativas para cada característica do comprador que pertença ao conjunto de características do fornecedor (13).

(30)

𝑆 = {𝑣𝑛1, … 𝑣𝑛𝑛} (1) 𝐶 = {𝑐𝑚1, … , 𝑐𝑚𝑛} (2) 𝐹 = {𝑓𝑟1, … , 𝑓𝑟𝑛} (3) 𝐶ℎ𝑟 = {𝑐ℎ1, … , 𝑐ℎ𝑡} (4) 𝑐𝑚𝑖 = {𝑜𝑏𝑔𝑖, 𝑜𝑝𝑡𝑖}, 𝑜𝑏𝑔𝑖 ⊆ 𝐶ℎ𝑟, 𝑜𝑝𝑡𝑖 ⊆ 𝐶ℎ𝑟, 𝑜𝑏𝑔𝑖⋂𝑜𝑝𝑡𝑖 = ∅ (5) 𝑓𝑟𝑖 = {𝑓𝐶ℎ𝑟𝑖, 𝑓𝐿𝑚𝑖, 𝑓𝐷𝑠𝑐𝑖}, 𝑓𝐶ℎ𝑟𝑖 ⊆ 𝐶ℎ𝑟 (6) 𝑓𝐿𝑚𝑖 = {𝑙𝑚0, … , 𝑙𝑚𝑙}, 𝑓𝐿𝑚𝑖 ⊂ ℕ (7) 𝑓𝐷𝑠𝑐𝑖 = {𝑑𝑠𝑐0, … , 𝑑𝑠𝑐𝑙−1}, 𝑓𝐷𝑠𝑐𝑖 ⊂ ℝ (8) 𝑣𝑛𝑖 = {𝑐𝑚𝑖, 𝑓𝑟𝑗} (9) 𝑊(𝑐𝑚𝑖, 𝑓𝑟𝑗) = {1 𝑠𝑒 𝑜𝑏𝑔0 𝑐𝑎𝑠𝑜 𝑐𝑜𝑛𝑡𝑟á𝑟𝑖𝑜𝑖 ⊆ 𝑓𝐶ℎ𝑟𝑗 (10) 𝑔𝑂𝑝𝑡(𝑐ℎ𝑖, 𝑓𝑟𝑗) = {𝑏𝑂𝑝𝑡 𝑠𝑒 𝑐ℎ𝑖 ∈ 𝑓𝐶ℎ𝑟𝑖 0 𝑐𝑎𝑠𝑜 𝑐𝑜𝑛𝑡𝑟á𝑟𝑖𝑜 (11) 𝑠𝐶𝑜𝑠𝑡𝑂𝑝𝑡(𝑆) = ∑𝑖0→𝑛𝑠𝐶𝑜𝑠𝑡𝑂𝑝𝑡𝐹𝑟(𝑣𝑛𝑖) (12) 𝑠𝐶𝑜𝑠𝑡𝑂𝑝𝑡𝐹𝑟(𝑣𝑛𝑖) = ∑ {𝑠𝑒 𝑐ℎ𝑘 ∈ 𝑜𝑝𝑡𝑖, 𝑔𝑂𝑝𝑡(𝑐ℎ𝑘, 𝑓𝑟𝑗) 0 𝑐𝑎𝑠𝑜 𝑐𝑜𝑛𝑡𝑟á𝑟𝑖𝑜 𝑘 0→𝑡 (13) 𝑠𝐶𝑜𝑠𝑡𝑂𝑏𝑔(𝑆) = 𝑠𝐶𝑜𝑠𝑡𝑂𝑏𝑔𝐹𝑟(𝑙𝑚𝐶𝑜𝑢𝑛𝑡(𝑆, 𝑓𝑟𝑗), 𝑓𝑟𝑗)(14) 𝑠𝐶𝑜𝑠𝑡𝑂𝑏𝑔𝐹𝑟(𝑙𝑚𝐶𝑜𝑢𝑛𝑡, 𝑓𝑟𝑗) = 𝑙𝑚𝐶𝑜𝑢𝑛𝑡 ∗ ∑𝑖0→𝑙−1{𝑑𝑠𝑐0 𝑐𝑎𝑠𝑜 𝑐𝑜𝑛𝑡𝑟á𝑟𝑖𝑜𝑖 𝑠𝑒 𝑙𝑚𝐶𝑜𝑢𝑛𝑡 > 𝑙𝑚𝑖 (15) 𝑙𝑚𝐶𝑜𝑢𝑛𝑡(𝑆, 𝑓𝑟𝑗) = ∑ {1 𝑠𝑒 ∀𝑐ℎ ∈ 𝑜𝑏𝑗𝑖, 𝑐ℎ ∈ 𝑓𝐶ℎ𝑟𝑗 0 𝑐𝑎𝑠𝑜 𝑐𝑜𝑛𝑡𝑟á𝑟𝑖𝑜 𝑖 0→𝑛 (16) 𝑠𝐶𝑜𝑠𝑡(𝑆, 𝑝𝑟𝑜𝑑𝐶𝑜𝑠𝑡) = 𝑝𝑟𝑜𝑑𝐶𝑜𝑠𝑡 ∗ (𝑛 − (𝑠𝐶𝑜𝑠𝑡𝑂𝑏𝑔(𝑆) + 𝑠𝐶𝑜𝑠𝑡𝑂𝑝𝑡(𝑆)) (17) 𝑏𝑂𝑝𝑡 = 𝑏ô𝑛𝑢𝑠 𝑑𝑎 𝑐𝑎𝑟𝑎𝑐𝑡𝑒𝑟í𝑠𝑡𝑖𝑐𝑎 𝑜𝑝𝑡𝑎𝑡𝑖𝑣𝑎 (18) 𝑝𝑟𝑜𝑑𝐶𝑜𝑠𝑡 = 𝑐𝑢𝑠𝑡𝑜 𝑑𝑜 𝑝𝑟𝑜𝑑𝑢𝑡𝑜 (19)

O custo total de uma solução pode ser dividido em duas categorias, referentes à sua origem: a redução de custo causada pelos descontos dos patamares é chamada de ganho ou desconto quantitativo; a redução de custo

(31)

causada pelo bônus das características optativas é chamada de ganho ou desconto qualitativo.

Um limite ou capacidade 𝑙𝑚𝑖 representa a quantidade de compradores necessárias para que o desconto 𝑑𝑠𝑐𝑖 seja ativado e contribua para a redução do custo da solução. A capacidade de um patamar é, portanto, a diferença entre o limite do patamar atual e o patamar anterior. Um caso especial é o limite 𝑙𝑚𝑙, referente ao último patamar, que representa a capacidade máxima do fornecedor, ou seja, a quantidade máxima de compradores que o fornecedor comporta.

Um comprador cm está vinculado a um fornecedor fr, ou um fornecedor fr está vinculado a um comprador cm, caso exista um vínculo 𝑣𝑛 = {𝑐𝑚, 𝑓𝑟}, 𝑣𝑛 ∈ 𝑆. Em outras palavras, um comprador está vinculado a um fornecedor se o comprador irá comprar desse fornecedor, ou se o fornecedor venderá o seu produto para esse comprador.

Um comprador é viável a um fornecedor, ou um fornecedor é viável a um comprador, caso seja possível realizar um vínculo entre eles que respeite a capacidade máxima do fornecedor e que as características obrigatórias do comprador sejam um subconjunto das características do fornecedor.

Uma solução é considerada válida caso todos os seus vínculos forem válidos. Uma alteração realizada em uma solução válida é considerada viável se a solução resultante também é válida. Uma solução é considerada inválida caso a quantidade de compradores vinculados a um fornecedor (16) seja maior do que a capacidade máxima 𝑙𝑚𝑖 do fornecedor, ou caso pelo menos um dos seus vínculos não seja viável. Neste trabalho, apenas as soluções válidas serão consideradas, onde os algoritmos serão responsáveis por realizarem operações viáveis, ou descartarem soluções inválidas.

Para resolver casos onde não seja possível vincular um comprador a nenhum fornecedor sem tornar a solução inválida, o comprador será considerado sem vínculo, ficando então sem fornecedor. Um comprador sem vínculo não terá ganhos quantitativos ou qualitativos, porém a solução ainda será considerada válida. Por questões de consistência, para manter a

(32)

cardinalidade da solução 𝑆, um comprador sem vínculo será representado por um vínculo 𝑣𝑚 = {𝑐𝑚, ∅} . Dentro do contexto do problema, isso representa uma situação onde o comprador não poderia participar dos descontos dos fornecedores, seja por não ter mais itens no estoque ou por nenhum dos produtos atender suas exigências, e seria, portanto, forçado a comprar em outro local.

(33)
(34)

3 Algoritmos de solução

Neste capítulo serão descritos os algoritmos utilizados para a solução do problema, explicando seus fundamentos e lógica de constituição, seu uso na literatura, como foram implementados e as decisões realizadas na implementação. Inicialmente, será definida a noção de função de potencial e serão descritas as funções de potencial desenvolvidas para este trabalho. Em seguida, serão descritas as heurísticas construtivas, o algoritmo exato utilizado para buscar a solução ótima das instâncias, as buscas locais utilizadas pelos algoritmos abordados neste trabalho, e finalmente os algoritmos heurísticos não construtivos.

Para todos os algoritmos utilizados neste trabalho, uma solução do problema será representada por um vetor 𝑠 de 𝑛 posições, onde 𝑛 é a quantidade de compradores na solução. O valor de um elemento 𝑠[𝑖] da solução representa que o comprador 𝑐𝑚𝑖 está vinculado ao fornecedor 𝑓𝑟𝑠[𝑖]. Caso o comprador não esteja vinculado, o valor do elemento 𝑠[𝑖] é -1.

A instância de um problema é composta de várias matrizes e vetores, contendo: preço do produto, quantidade de compradores, quantidade de fornecedores, quantidade de patamares e descontos em cada fornecedor, quantidade de características, quantidade de características optativas e obrigatórias em cada comprador, bônus das características optativas, capacidade e desconto de cada patamar, capacidade máxima de cada fornecedor, e características obrigatórias e características optativas de cada comprador.

Além dos dados da instância, também serão fornecidos algumas informações, calculadas a partir de vários pré-cálculos, realizados no início dos algoritmos caso estes necessitem. As informações pré-calculadas disponíveis são: para cada fornecedor, quais são os compradores viáveis, e os seus respectivos ganhos qualitativos; e para cada par de fornecedores, quais compradores são viáveis a ambos.

(35)

3.1 Funções de potencial

No sentido de auxiliar a avaliação de um esquema de compras em construção, será introduzido o conceito de função de potencial, utilizado por vários dos algoritmos e funções deste trabalho. As funções de potencial são funções matemáticas que calculam o potencial de um fornecedor a partir dos descontos e capacidades dos seus patamares e a quantos compradores ele está vinculado. A ideia de uma função de potencial é, dado um fornecedor e quantos compradores estão vinculados a ele, representar numericamente o quão vantajoso seria, em longo prazo, vincular um novo comprador a este fornecedor.

Neste trabalho, são utilizadas três funções de potencial, com diferenças de acordo com o seu escopo: função de potencial de escopo local, função de potencial de escopo semi-global e função de potencial de escopo global. O escopo define quais informações são utilizadas para calcular o potencial, e qual é o objetivo do seu potencial.

A função de potencial de escopo local (fpel), mostrada no Algoritmo 1, busca calcular o potencial de um fornecedor baseado no seu patamar ativo e no próximo desconto a ser ativado. A função (20) utilizada para calcular o potencial é:

𝑓𝑝𝑒𝑙(𝑓) = 𝑝𝑟𝑥𝐷𝑠𝑐(𝑓) ∗𝑞𝑡𝑁𝑠𝑐𝑃𝑟𝑥𝐷𝑠𝑐(𝑓)𝑝𝑟𝑥𝐷𝑠𝑐𝐿𝑚𝑡(𝑓) (20) Onde dado um fornecedor 𝑓, 𝑝𝑟𝑥𝐷𝑠𝑐(𝑓) é o valor do próximo desconto a ser ativado neste fornecedor, 𝑝𝑟𝑥𝐷𝑠𝑐𝐿𝑚𝑡(𝑓) é a capacidade de compradores do fornecedor até o patamar atual, e 𝑞𝑡𝑁𝑠𝑐𝑃𝑟𝑥𝐷𝑠𝑐(𝑓) a quantidade de compradores que ainda precisam ser vinculados para que o próximo desconto seja ativado. Essa função de potencial é considerada de escopo local por levar em consideração apenas o próximo desconto ainda não ativado, buscando apenas ativá-lo. Pela fórmula é possível perceber que o potencial é diretamente proporcional ao valor do desconto a ser ativado e à quantidade de compradores que receberão esse desconto, e é inversamente proporcional à quantidade de compradores que ainda precisam ser vinculados.

(36)

Algoritmo 1. Pseudocódigo do algoritmo de cálculo de função de potencial de escopo

local

Algoritmo funcPotEL(forn,comprVinc)

𝑓𝑜𝑟𝑛 ← fornecedor cujo potencial será calculado

𝑐𝑜𝑚𝑝𝑟𝑉𝑖𝑛𝑐 ← quantidade de compradores vinculados ao fornecedor 𝑓𝑜𝑟𝑛 𝑝𝑎𝑡𝑎𝑚𝑎𝑟 ← patamar atual do fornecedor 𝑖

𝑐𝑎𝑝𝑇𝑜𝑡𝑎𝑙 ← capacidade total do patamar 𝑐𝑎𝑝[𝑖] ← capacidade do patamar 𝑖 𝑑𝑒𝑠𝑐𝑜𝑛𝑡𝑜[𝑖] ← desconto do patamar 𝑖

𝑐𝑎𝑙𝑐𝑢𝑙𝑎𝑟𝑃𝑎𝑡𝑎𝑚𝑎𝑟𝐴𝑡𝑢𝑎𝑙(𝑖, 𝑐𝑜𝑚𝑝𝑟𝑉𝑖𝑛𝑐) ← função para encontrar o patamar ativo no fornecedor 𝑖 1 𝑝𝑎𝑡𝑎𝑚𝑎𝑟 ← 𝑐𝑎𝑙𝑐𝑢𝑙𝑎𝑟𝑃𝑎𝑡𝑎𝑚𝑎𝑟𝐴𝑡𝑢𝑎𝑙(𝑖, 𝑐𝑜𝑚𝑝𝑟𝑉𝑖𝑛𝑐); 2 𝑐𝑎𝑝𝑇𝑜𝑡𝑎𝑙 ← 0; 3 Para 𝑖 de 0 a 𝑝𝑎𝑡𝑎𝑚𝑎𝑟: 4 𝑐𝑎𝑝𝑇𝑜𝑡𝑎𝑙 ← 𝑐𝑎𝑝𝑇𝑜𝑡𝑎𝑙 + 𝑐𝑎𝑝[𝑖]; 5 Retornar 𝑑𝑒𝑠𝑐𝑜𝑛𝑡𝑜[𝑝𝑎𝑡𝑎𝑚𝑎𝑟] ∗𝑐𝑎𝑝𝑇𝑜𝑡𝑎𝑙−𝑐𝑜𝑚𝑝𝑟𝑉𝑖𝑛𝑐𝑐𝑎𝑝[𝑝𝑎𝑡𝑎𝑚𝑎𝑟] ;

A função de potencial de escopo semi-global (fpesg), mostrada no Algoritmo 2, se diferencia do escopo local por levar em consideração a capacidade total do fornecedor. A função (21) utilizada para calcular o potencial é:

𝑓𝑝𝑒𝑠𝑔(𝑓) = 𝑝𝑟𝑥𝐷𝑠𝑐(𝑓) ∗𝑞𝑡𝑁𝑠𝑐𝐿𝑚𝑡(𝑓)𝑓𝑟𝑛𝐿𝑚𝑡(𝑓) (21) Onde dado um fornecedor 𝑓, a função 𝑝𝑟𝑥𝐷𝑠𝑐(𝑓) retorna o valor do próximo desconto a ser ativado no fornecedor, a função 𝑓𝑟𝑛𝐿𝑚𝑡(𝑓) retorna a capacidade máxima de compradores no fornecedor, e a função 𝑞𝑡𝑁𝑠𝑐𝐿𝑚𝑡(𝑓) retorna a quantidade de compradores que ainda precisam ser vinculados para que o fornecedor alcance sua capacidade máxima. Essa função é considerada de escopo semi-global por ter um escopo maior do que o escopo local, levando em consideração a capacidade máxima do fornecedor, mas ainda não leva em consideração o caso mais abrangente do fornecedor, que será trabalhado pela função de potencial a seguir.

(37)

Algoritmo 2. Pseudocódigo do algoritmo de cálculo de função de potencial de escopo

semi-global

Algoritmo funcPotESG(forn,comprVinc)

𝑓𝑜𝑟𝑛 ← fornecedor cujo potencial será calculado

𝑐𝑜𝑚𝑝𝑟𝑉𝑖𝑛𝑐 ← quantidade de compradores vinculados ao fornecedor 𝑓𝑜𝑟𝑛 𝑝𝑎𝑡𝑎𝑚𝑎𝑟 ← patamar atual do fornecedor 𝑖

𝑐𝑎𝑝𝑀𝑎𝑥 ← capacidade máxima do fornecedor 𝑑𝑒𝑠𝑐𝑜𝑛𝑡𝑜[𝑖] ← desconto do patamar 𝑖

𝑐𝑎𝑙𝑐𝑢𝑙𝑎𝑟𝑃𝑎𝑡𝑎𝑚𝑎𝑟𝐴𝑡𝑢𝑎𝑙(𝑖, 𝑐𝑜𝑚𝑝𝑟𝑉𝑖𝑛𝑐) ← função para encontrar o patamar ativo no fornecedor 𝑖

1 𝑝𝑎𝑡𝑎𝑚𝑎𝑟 ← 𝑐𝑎𝑙𝑐𝑢𝑙𝑎𝑟𝑃𝑎𝑡𝑎𝑚𝑎𝑟𝐴𝑡𝑢𝑎𝑙(𝑖, 𝑐𝑜𝑚𝑝𝑟𝑉𝑖𝑛𝑐); 2 Retornar 𝑑𝑒𝑠𝑐𝑜𝑛𝑡𝑜[𝑝𝑎𝑡𝑎𝑚𝑎𝑟] ∗ 𝑐𝑎𝑝𝑀𝑎𝑥

𝑐𝑎𝑝𝑀𝑎𝑥−𝑐𝑜𝑚𝑝𝑟𝑉𝑖𝑛𝑐;

A função de potencial de escopo global (fpeg), mostrada no Algoritmo 3, leva em consideração todos os descontos e a sua capacidade máxima do fornecedor. A função (22) utilizada para calcular o potencial é:

𝑓𝑝𝑒𝑔(𝑓) = 𝑓𝑟𝑛𝐷𝑠𝑐(𝑓) ∗𝑞𝑡𝑁𝑠𝑐𝐿𝑚𝑡(𝑓)𝑓𝑟𝑛𝐿𝑚𝑡(𝑓) (22) Onde dado um fornecedor 𝑓 , 𝑓𝑟𝑛𝐷𝑠𝑐(𝑓) é o somatório dos descontos do fornecedor, 𝑓𝑟𝑛𝐿𝑚𝑡(𝑓) a capacidade máxima de compradores no fornecedor, e 𝑞𝑡𝑁𝑠𝑐𝐿𝑚𝑡(𝑓) a quantidade de compradores que ainda precisam ser vinculados para que o fornecedor alcance sua capacidade máxima.

Algoritmo 3. Pseudocódigo do algoritmo de cálculo de função de potencial de escopo

global

Algoritmo funcPotESG(forn,comprVinc)

𝑓𝑜𝑟𝑛 ← fornecedor cujo potencial será calculado

𝑐𝑜𝑚𝑝𝑟𝑉𝑖𝑛𝑐 ← quantidade de compradores vinculados ao fornecedor 𝑓𝑜𝑟𝑛 𝑝𝑎𝑡𝑎𝑚𝑎𝑟 ← patamar atual do fornecedor 𝑖

𝑐𝑎𝑝𝑀𝑎𝑥 ← capacidade máxima do fornecedor 𝑑𝑒𝑠𝑐𝑜𝑛𝑡𝑜𝑀𝑎𝑥 ← desconto máximo do fornecedor

𝑐𝑎𝑙𝑐𝑢𝑙𝑎𝑟𝑃𝑎𝑡𝑎𝑚𝑎𝑟𝐴𝑡𝑢𝑎𝑙(𝑖, 𝑐𝑜𝑚𝑝𝑟𝑉𝑖𝑛𝑐) ← função para encontrar o patamar ativo no fornecedor 𝑖

1 𝑝𝑎𝑡𝑎𝑚𝑎𝑟 ← 𝑐𝑎𝑙𝑐𝑢𝑙𝑎𝑟𝑃𝑎𝑡𝑎𝑚𝑎𝑟𝐴𝑡𝑢𝑎𝑙(𝑖, 𝑐𝑜𝑚𝑝𝑟𝑉𝑖𝑛𝑐); 2 Retornar 𝑑𝑒𝑠𝑐𝑜𝑛𝑡𝑜𝑀𝑎𝑥 ∗ 𝑐𝑎𝑝𝑀𝑎𝑥

(38)

Essas funções buscam categorizar, a partir da quantidade de compradores em cada fornecedor, qual fornecedor seria a melhor opção para vincular um novo comprador, levando em consideração o desconto a ser ativado e ganho pelos compradores, quantos compradores serão beneficiados por esse novo desconto, ou pelos descontos já existentes, e quantos compradores ainda são necessários para que o próximo desconto seja ativado, ou para que a meta de compradores seja alcançada. Cada um dos escopos busca isso de uma maneira diferente: o escopo local possui o foco apenas no patamar atual do fornecedor, buscando ativar o desconto com o maior custo-benefício; o escopo semi-global analisa o patamar atual em relação a todos os compradores que estão ou serão vinculados ao fornecedor, dando então o maior potencial para o fornecedor que possua um desconto a ser ativado que beneficie o máximo de compradores no futuro; e o escopo global, que analisa apenas a situação ideal do fornecedor, comparando o valor total dos descontos com a capacidade máxima do fornecedor.

3.2 Algoritmo branch-and-bound

Diferente dos outros algoritmos abordados neste trabalho, o algoritmo branch-and-bound será utilizado para buscar uma solução exata da instância. Este algoritmo explora todo o espaço de soluções construindo uma árvore, onde seus nós representam soluções parciais, e suas folhas representam soluções completas. A geração dessa árvore é feita a partir de operações de branching, adicionando novos vértices e criando novas subárvores, e as operações de bounding, que evitam a criação uma nova subárvore caso seja garantido que ela não construirá uma solução que seja melhor que a melhor solução já encontrada pelo algoritmo. Essa garantia é feita a partir do limite superior e de uma função de limite inferior.

O limite superior é o custo da melhor solução parcial do algoritmo, sendo então o menor custo para os problemas de minimização e o maior custo para os problemas de maximização. A função de limite inferior é uma estimativa do custo da melhor solução que será encontrada em uma dada subárvore, onde é garantido que a estimativa sempre será melhor do que a

(39)

solução ótima. A operação de bounding compara o resultado do limite inferior com o limite superior, e caso este seja melhor que o limite inferior, então se garante que não é possível encontrar uma solução com o custo melhor que o limite superior nesta subárvore.

O branch-and-bound inicia sua execução a partir de um vértice raiz, vazio, representando uma solução vazia. Para cada operação de construção que adicione um novo elemento à solução vazia, o algoritmo então aplica o branching, gerando um novo vértice contendo essa solução parcial, e então aplica o bounding, eliminando a subárvore, caso não seja possível encontrar uma solução de custo melhor que o limite superior. O algoritmo trabalha recursivamente, aplicando as regras de branching e bounding, gerando subárvores apenas quando seja provável encontrar uma nova melhor solução. Caso um novo vértice seja formado a partir de uma solução completa, essa solução é então comparada com a melhor solução parcial, e caso o seu custo seja melhor que o limite superior, essa nova solução é então considerada como melhor solução, e o seu custo é considerado o novo limite superior.

O algoritmo roda recursivamente, explorando as soluções parciais e retirando aquelas que é possível garantir que sua exploração não trará resultados melhores, até que todas soluções completas sejam exploradas ou ignoradas. No final da sua execução, a melhor solução encontrada pelo algoritmo será a solução ótima da instância. Apesar de ser um algoritmo exato e rodar em complexidade exponencial, a utilização das operações de branching e bounding reduzem o tempo de execução, fazendo com que o seu tempo de execução para alguns problemas se torne viável.

3.2.1 Funcionamento e implementação

Antes de definir como foi implementado o algoritmo, é necessário antes definir o que seria uma solução parcial, e qual será a operação de adição utilizada. Uma solução vazia para o nosso problema é uma solução onde nenhum comprador ou fornecedor está vinculado. Com isso, uma solução parcial é uma solução não-válida onde apenas um grupo de compradores

(40)

está vinculado. Caso todos sejam vinculados, então temos uma solução completa e válida.

O branch-and-bound vincula os compradores aos fornecedores sequencialmente, seguindo a ordem dos compradores. Isso significa que todas as soluções de um mesmo nível da árvore do branch-and-bound terão os mesmos compradores vinculados, e que cada nível terá uma quantidade diferente de compradores vinculados.

O algoritmo branch-and-bound começa com uma solução vazia como nó raiz, e cria uma solução parcial vinculando o primeiro comprador ao primeiro fornecedor viável. O limite inferior é calculado e comparado com o limite superior, e caso ou limite superior não exista ou seja maior que o limite inferior, uma nova solução será criada a partir da solução parcial anterior, vinculando então o segundo comprador ao primeiro fornecedor válido. Isso será repetido recursivamente, até que seja gerada uma solução completa, e então essa solução será comparada ao limite superior, e caso o seu custo seja menor, será guardada como a melhor solução encontrada, e o limite superior passará a ser o custo desta solução. Após a primeira subárvore de um nó for completada (todas as soluções completas possíveis sejam encontradas ou ignoradas pelo bounding), o algoritmo irá então gerar uma nova solução parcial vinculando o n-ésimo comprador ao segundo fornecedor viável. Isso se repetirá até não existirem mais fornecedores viáveis para o n-ésimo comprador na solução parcial do nó, e portanto este nó não terá mais operações possíveis, e o algoritmo voltará então para o nó pai e fará o mesmo trabalho de vincular a novos fornecedores ou voltar para o nó pai. O Algoritmo 4 mostra o pseudocódigo para o algoritmo branch-and-bound implementado com a utilização de dois limites inferiores.

Na implementação utilizada neste trabalho, é necessário decidir a função de limite inferior e o limite superior utilizado. Umas das opções é utilizar uma solução inicial gerada por uma heurística como limite superior, onde uma boa solução significa que o bounding irá ignorar subárvores em níveis mais altos do que faria com um limite superior aleatório. A escolha desse limite superior será feito após os experimentos computacionais, onde a

(41)

partir dos resultados encontrados nós escolheremos uma heurística para encontrar o limite superior inicial.

A função de limite inferior calcula um custo estimado da melhor solução possível para cada subárvore, e caso esse limite inferior seja pior que o limite superior (em um problema de minimização, tenha um custo maior), então aquela subárvore não será explorada. Para o limite inferior, serão utilizados dois algoritmos, nomeados limite inferior por multiplicação (li-m) e limite inferior por abstração (li-a).

O limite inferior por multiplicação (li-m), mostrado no Algoritmo 5, busca encontrar um limite inferior multiplicando os compradores que ainda não foram vinculados, de tal forma que cada comprador não vinculado possua cópias suficientes para se vincular a todos os fornecedores viáveis. Em questão do ganho qualitativo (características optativas), os compradores não vinculados recebem o ganho qualitativo máximo ( 𝑏ô𝑛𝑢𝑠 𝑜𝑝𝑡𝑎𝑡𝑖𝑣𝑜 ∗ 𝑞𝑢𝑎𝑛𝑡𝑖𝑑𝑎𝑑𝑒 𝑑𝑒 𝑐𝑎𝑟𝑎𝑐𝑡𝑒𝑟í𝑠𝑡𝑖𝑐𝑎𝑠 𝑜𝑝𝑡𝑎𝑡𝑖𝑣𝑎𝑠). O algoritmo então calcula o custo da solução alterada, e utiliza o seu valor como limite inferior.

O limite inferior por abstração (li-a), mostrado no Algoritmo 6, busca encontrar um limite inferior abstraindo as restrições de características obrigatórias para os compradores não vinculados e maximizando o desconto de cada fornecedor. Em outras palavras, os fornecedores passam a ser viáveis para todos os compradores não vinculados, e todo os compradores receberão o desconto máximo do fornecedor a quem estiverem vinculados. Assim como o limite por multiplicação, os compradores não-vinculados recebem o ganho qualitativo máximo.

A escolha de implementar dois limites inferiores se deve ao comportamento do ganho quantitativo do limite inferior por multiplicação. No melhor caso, as cópias dos compradores não vinculados não serão vinculadas, seja porque o fornecedor já alcançou a capacidade máxima, seja pelo fato do comprador original só possuir um fornecedor viável. Porém, no pior caso, todas as cópias dos compradores não vinculados receberão algum tipo de ganho quantitativo. O limite inferior de abstração foi implementado para encontrar limites inferiores mais próximos da solução ótima nos piores

(42)

casos e para as soluções parciais com menos compradores vinculados.

Algoritmo 4. Pseudocódigo da implementação do algoritmo branch-and-bound. O limite

superior inicial deve ser encontrado por meio de outro algoritmo

Algoritmo branchAndBound(melhor, sol, p)

𝑡𝑎𝑚𝑆𝑜𝑙 ← tamanho da solução sol

𝑉𝑝[𝑘] ← conjunto de elementos que podem ser adicionados à solução 𝑠𝑜𝑙 na posição 𝑝

𝑠𝑜𝑙 ← solução atual

𝑚𝑒𝑙ℎ𝑜𝑟 ← melhor solução encontrada 1 Se 𝑡𝑎𝑚𝑆𝑜𝑙 ≠ 𝑝:

2 Para cada elemento 𝑣 ∈ 𝑉: 3 𝑠𝑜𝑙[𝑝] ← 𝑣; 4 Se 𝑙𝑖𝑚𝑖𝑡𝑒𝐼𝑛𝑓𝑒𝑟𝑖𝑜𝑟1(𝑠𝑜𝑙, 𝑝) < 𝑚𝑒𝑙ℎ𝑜𝑟. 𝑐𝑢𝑠𝑡𝑜 e 𝑙𝑖𝑚𝑖𝑡𝑒𝐼𝑛𝑓𝑒𝑟𝑖𝑜𝑟2(𝑠𝑜𝑙, 𝑝) < 𝑚𝑒𝑙ℎ𝑜𝑟. 𝑐𝑢𝑠𝑡𝑜: 5 𝑏𝑟𝑎𝑛𝑐ℎ𝐴𝑛𝑑𝐵𝑜𝑢𝑛𝑑(𝑚𝑒𝑙ℎ𝑜𝑟, 𝑠𝑜𝑙, 𝑝 + 1); 6 Senão: 7 Se 𝑚𝑒𝑙ℎ𝑜𝑟. 𝑐𝑢𝑠𝑡𝑜 > 𝑠𝑜𝑙. 𝑐𝑢𝑠𝑡𝑜: 8 𝑚𝑒𝑙ℎ𝑜𝑟 ← 𝑠𝑜𝑙; 9 𝑚𝑒𝑙ℎ𝑜𝑟. 𝑐𝑢𝑠𝑡𝑜 ← 𝑠𝑜𝑙. 𝑐𝑢𝑠𝑡𝑜;

Algoritmo 5. Pseudocódigo do algoritmo de limite inferior por multiplicação

Algoritmo liM(sol, p)

𝑞𝑛𝑡[𝑖] ← quantidade real de compradores no fornecedor 𝑖 𝑒𝑠𝑡[𝑖] ← quantidade estimada de compradores no fornecedor 𝑖 𝑙𝑖𝑚𝑖𝑡𝑒𝑇𝑜𝑡𝑎𝑙[𝑖] ← capacidade máxima do fornecedor 𝑖

𝑓𝑜𝑟𝑛𝑄𝑡 ← quantidade de fornecedores 𝑐𝑜𝑚𝑝𝑟𝑄𝑡 ← quantidade de compradores

𝑏𝑜𝑛𝑢𝑠[𝑖][𝑗] ← bônus das características optativas do comprador 𝑗 no fornecedor 𝑖 𝑐ℎ𝑟𝐵𝑜𝑛𝑢𝑠 ← valor do bônus de uma característica optativa

𝑐ℎ𝑎𝑟𝑎𝑐𝑂𝑝𝑡 ← quantidade de características optativas em um comprador 𝑣𝑎𝑙𝑜𝑟𝑃𝑟𝑜𝑑 ← valor do produto 1 Para 𝑖 de 0 a 𝑝: 2 𝑞𝑛𝑡[𝑠𝑜𝑙[𝑖]] ← 𝑞𝑛𝑡[𝑠𝑜𝑙[𝑖]] + 1; 3 𝑡𝑜𝑡𝑎𝑙 ← 𝑡𝑜𝑡𝑎𝑙 + 𝑏𝑜𝑛𝑢𝑠[𝑠𝑜𝑙[𝑖]][𝑖]; 4 Para 𝑖 de 𝑝 a 𝑐𝑜𝑚𝑝𝑟𝑄𝑡: 5 Para 𝑗 de 0 a 𝑓𝑜𝑟𝑛𝑄𝑡:

6 Se a solução 𝑖 pode se vincular ao fornecedor 𝑗: 7 𝑒𝑠𝑡[𝑖] ← 𝑒𝑠𝑡[𝑖] + 1;

(43)

8 𝑡𝑜𝑡𝑎𝑙 ← 𝑡𝑜𝑡𝑎𝑙 + 𝑐ℎ𝑎𝑟𝑎𝑐𝑂𝑝𝑡 ∗ 𝑐ℎ𝑟𝐵𝑜𝑛𝑢𝑠; 9 Para 𝑖 de 0 a 𝑓𝑜𝑟𝑛𝑄𝑡: 10 Se 𝑙𝑖𝑚𝑖𝑡𝑒𝑇𝑜𝑡𝑎𝑙[𝑖] ≤ 𝑞𝑛𝑡[𝑖]: 11 Retornar 𝑐𝑜𝑚𝑝𝑟𝑄𝑡 ∗ 𝑣𝑎𝑙𝑜𝑟𝑃𝑟𝑜𝑑; 12 𝑞𝑛𝑡[𝑖] ← 𝑞𝑛𝑡[𝑖] + 𝑒𝑠𝑡[𝑖]; 13 Se 𝑙𝑖𝑚𝑖𝑡𝑒𝑇𝑜𝑡𝑎𝑙[𝑖] ≤ 𝑞𝑛𝑡[𝑖]: 14 𝑞𝑛𝑡 ← 𝑙𝑖𝑚𝑖𝑡𝑒𝑇𝑜𝑡𝑎𝑙[𝑖];

15 𝑑𝑠𝑐𝐿𝑒𝑣𝑒𝑙[𝑖] ← desconto ganho caso 𝑞𝑛𝑡[𝑖] compradores sejam vinculados ao fornecedor 𝑖;

16 𝑡𝑜𝑡𝑎𝑙 ← 𝑡𝑜𝑡𝑎𝑙 + 𝑑𝑠𝑐𝐿𝑒𝑣𝑒𝑙[𝑖] ∗ 𝑞𝑛𝑡[𝑖]; 17 Retornar 𝑐𝑜𝑚𝑝𝑟𝑄𝑡 ∗ 𝑣𝑎𝑙𝑜𝑟𝑃𝑟𝑜𝑑 − 𝑡𝑜𝑡𝑎𝑙;

Algoritmo 6. Pseudocódigo do algoritmo de limite inferior por abstração

Algoritmo liA(sol, p)

𝑞𝑛𝑡[𝑖] ← quantidade real de compradores no fornecedor 𝑖 𝑒𝑠𝑡[𝑖] ← quantidade estimada de compradores no fornecedor 𝑖 𝑙𝑖𝑚𝑖𝑡𝑒𝑇𝑜𝑡𝑎𝑙[𝑖] ← capacidade máxima do fornecedor 𝑖

𝑑𝑒𝑠𝑐𝑇𝑜𝑡𝑎𝑙[𝑖] ←desconto máximo do fornecedor 𝑖 𝑓𝑜𝑟𝑛𝑄𝑡 ← quantidade de fornecedores

𝑐𝑜𝑚𝑝𝑟𝑄𝑡 ← quantidade de compradores

𝑏𝑜𝑛𝑢𝑠[𝑖][𝑗] ← bônus das características optativas do comprador 𝑗 no fornecedor 𝑖 𝑐ℎ𝑟𝐵𝑜𝑛𝑢𝑠 ← valor do bônus de uma característica optativa

𝑐ℎ𝑎𝑟𝑎𝑐𝑂𝑝𝑡 ← quantidade de características optativas em um comprador 𝑣𝑎𝑙𝑜𝑟𝑃𝑟𝑜𝑑 ← valor do produto 1 Para 𝑖 de 0 a 𝑓𝑜𝑟𝑛𝑄𝑡: 2 𝑑𝑒𝑠𝑐𝑇𝑜𝑡𝑎𝑙[𝑖] ← 𝑑𝑒𝑠𝑐𝑇𝑜𝑡𝑎𝑙[𝑖] + 𝑐ℎ𝑟𝐵𝑜𝑛𝑢𝑠 ∗ 𝑐ℎ𝑎𝑟𝑎𝑐𝑂𝑝𝑡; 3 Para 𝑖 de 0 a 𝑝: 4 𝑡𝑜𝑡𝑎𝑙 ← 𝑑𝑒𝑠𝑐𝑇𝑜𝑡𝑎𝑙[𝑠𝑜𝑙[𝑖]]; 5 𝑙𝑖𝑚𝑖𝑡𝑒𝑇𝑜𝑡𝑎𝑙[𝑠𝑜𝑙[𝑖]] ← 𝑙𝑖𝑚𝑖𝑡𝑒𝑇𝑜𝑡𝑎𝑙[𝑠𝑜𝑙[𝑖]] − 1; 6 𝑟𝑒𝑠𝑡𝑎𝑛𝑡𝑒 ← 𝑐𝑜𝑚𝑝𝑟𝑄𝑡 − 𝑝; 7 Enquanto 𝑟𝑒𝑠𝑡𝑎𝑛𝑡𝑒 > 0:

8 𝑚𝑒𝑙ℎ𝑜𝑟𝐷𝑒𝑠𝑐 ← fornecedor com o 𝑑𝑒𝑠𝑐𝑇𝑜𝑡𝑎𝑙 de maior valor; 9 Se 𝑙𝑖𝑚𝑖𝑡𝑒𝑇𝑜𝑡𝑎𝑙[𝑚𝑒𝑙ℎ𝑜𝑟𝐷𝑒𝑠𝑐] ≤ 𝑟𝑒𝑠𝑡𝑎𝑛𝑡𝑒: 10 𝑡𝑜𝑡𝑎𝑙 ← 𝑡𝑜𝑡𝑎𝑙 + 𝑟𝑒𝑠𝑡𝑎𝑛𝑡𝑒 ∗ 𝑑𝑒𝑠𝑐𝑇𝑜𝑡𝑎𝑙[𝑚𝑒𝑙ℎ𝑜𝑟𝐷𝑒𝑠𝑐]; 11 𝑟𝑒𝑠𝑡𝑎𝑛𝑡𝑒 ← 𝑟𝑒𝑠𝑡𝑎𝑛𝑡𝑒 − 𝑙𝑖𝑚𝑖𝑡𝑒𝑇𝑜𝑡𝑎𝑙[𝑚𝑒𝑙ℎ𝑜𝑟𝐷𝑒𝑠𝑐]; 12 𝑑𝑒𝑠𝑐𝑇𝑜𝑡𝑎𝑙[𝑚𝑒𝑙ℎ𝑜𝑟𝐷𝑒𝑠𝑐] ← 0; 13 Senão: 14 𝑡𝑜𝑡𝑎𝑙 ← 𝑡𝑜𝑡𝑎𝑙 + 𝑙𝑖𝑚𝑖𝑡𝑒𝑇𝑜𝑡𝑎𝑙[𝑚𝑒𝑙ℎ𝑜𝑟𝐷𝑒𝑠𝑐] ∗ 𝑑𝑒𝑠𝑐𝑇𝑜𝑡𝑎𝑙[𝑚𝑒𝑙ℎ𝑜𝑟𝐷𝑒𝑠𝑐]; 15 Retornar 𝑐𝑜𝑚𝑝𝑟𝑄𝑡 ∗ 𝑣𝑎𝑙𝑜𝑟𝑃𝑟𝑜𝑑 − 𝑡𝑜𝑡𝑎𝑙;

Referências

Documentos relacionados

xii) número de alunos matriculados classificados de acordo com a renda per capita familiar. b) encaminhem à Setec/MEC, até o dia 31 de janeiro de cada exercício, para a alimentação de

A combinação dessas dimensões resulta em quatro classes de abordagem comunicativa, que podem ser exemplificadas da seguinte forma: interativo/dialógico: professor e

•   O  material  a  seguir  consiste  de  adaptações  e  extensões  dos  originais  gentilmente  cedidos  pelo 

Deste modo, o adequado zoneamento e sua observância são fundamentais para a conciliação da preservação ou conservação de espécies, hábitats e paisagens dentre outras e

As variáveis peso, estatura e circunferência da cintura apresentaram valores médios superiores aos homens em relação as mulheres, sendo o inverso observado para índice

O enfermeiro, como integrante da equipe multidisciplinar em saúde, possui respaldo ético legal e técnico cientifico para atuar junto ao paciente portador de feridas, da avaliação

The purpose of this study is to recognize and describe anatomical variations of the sphenoid sinus and the parasellar region, mainly describing the anatomy of

O romance Usina, diferentemente dos demais do conjunto da obra pertencente ao ciclo-da-cana-de-açúcar, talvez em função do contexto histórico em que se insere, não