Esse trabalho aborda o problema do sequenciamento (scheduling) de tarefas, que consiste no
estudo da ordem de entrada de diferentes tarefas a serem executadas em máquinas de produção.
Obter o melhor sequenciamento possível significa reduzir o tempo total de trabalho (makespan)
dessas máquinas, sendo esse o motivo desse trabalho. A solução adotada emprega o uso da
metaheurística GRASP, no qual os resultados serão mostrados nesse documento.
Estudar, para quê? Ciência, para quê? Parte 1 e Parte 2
METAHEURÍSTICA GRASP APLICADA AO PROBLEMA DO SEQUENCIAMENTO DE TAREFAS
1. UNIVERSIDADE ESTADUAL DO CEARÁ
CENTRO DE CIÊNCIAS E TECNOLOGIA
CURSO DE GRADUAÇÃO EM CIÊNCIA DA COMPUTAÇÃO
JOÃO GONÇALVES FILHO & RAPHAEL BEZERRA DO NASCIMENTO
JOAOMSA3@GMAIL.COM & RAPHAELBN10@GMAIL.COM
TRABALHO DE PROJETO E ANÁLISE DE
ALGORITMOS: METAHEURÍSTICA GRASP APLICADA
AO PROBLEMA DO SEQUENCIAMENTO DE TAREFAS
FORTALEZA - CEARÁ
2013
2. RESUMO
Esse trabalho aborda o problema do sequenciamento (scheduling) de tarefas, que consiste no
estudo da ordem de entrada de diferentes tarefas a serem executadas em máquinas de produção.
Obter o melhor sequenciamento possível significa reduzir o tempo total de trabalho (makespan)
dessas máquinas, sendo esse o motivo desse trabalho. A solução adotada emprega o uso da
metaheurística GRASP, no qual os resultados serão mostrados nesse documento.
4. 3
1
INTRODUÇÃO
O problema do sequenciamento é uma da classe de problemas em que pode ser inviável
uma tentativa de solução com força bruta, nesse caso precisamos buscar heurísticas que nos der
um resultado que com uma boa solução, mesmo não sendo a exata. Nesse trabalho usamos
a metaheurística grasp, uma abordagem simples, mas que nos dar boas soluções com rápida
implementação, como iremos mostrar no restante desse trabalho.
5. 4
2
2.1
DEFINIÇÃO DO PROBLEMA DO SEQUENCIAMENTO DE TAREFAS
Objetivo
Alocar máquinas e tarefas de modo a minimizar o makespan numa linha de produção.
2.2
Job Shop(JSSP)
Se caracteriza por conjunto de trabalhos em um conjunto de máquinas, sujeito à restrição de que cada máquina pode lidar com no máximo uma tarefa de cada vez e fato de que cada
trabalho tem uma ordem de processamento especificado através das máquinas.
2.3
Flow Shop(FSSP)
FSSP é um caso especial de JSSP onde existe uma ordem rigorosa de todas as operações a serem realizadas em todos os trabalhos. Em nosso trabalho FSSP significa que a ordem
de processamento dos trabalhos sobre as maquinas é o mesmo para cada etapa subsequente de
processamento.
2.4
Aplicações
(CUNHA, 2003) mostra uma aplicação real em que um problema de sequenciamento
é a alocação de um conjunto de gerentes, de uma determinada instituição, para visitar clientes
diariamente em busca de vender seus produtos e conquistar mais clientes. Essas visitas são
definidas em um dia anterior, em um sistema de call center, com hora marcada para cada cliente.
Esse problema pode ser resolvido como um problema de sequenciamento pois os gerentes se
encontram em diferentes filiais da empresa, e cada gerente deve atender uma quantidade de
clientes definida, tendo um tempo previsto para cada atendimento e tempo de deslocamento
entre um cliente e outro. O objetivo seria alocar esses gerentes de forma a reduzir o tempo de
deslocamento dos gerentes e maximar a quantidade de atendimento ao dia.
Uma outra aplicação mostrado por (MÜLLER; LIMBERGER, 2000) para o problema
de sequenciamento, é o processamento de n tarefas independentes J1, J2, ... , Jn em m processadores uniformes M1, M2, ... , Mm, sem preempção. Este problema se caracteriza por um
problema de sequenciamento, pois cada tarefa possui um tempo de processamento e cada processador possui uma velocidade de operação. Nesse caso o objetivo seria a redução do tempo
total de processamento das tarefas nos processadores.
6. 5
2.5
Problema
“Determinar a sequência de fabricação de fios a ser utilizada para garantir que sua
produção mensal seja concluída no menor tempo”.
Dado um conjunto de N tarefas (N fios a serem produzidos) e M máquinas, temos:
• Cada tarefa será processada por M maquinas;
• O fluxo de processamento das N tarefas nas M máquinas é o mesmo para todas as tarefas;
• Uma tarefa só poderá iniciar na próxima maquina, caso tenha sido finalizada na maquina
anterior;
• Uma máquina processa apenas uma operação de cada vez, e não deve ser interrompida
até sua conclusão;
• São conhecidos os tempos de processamento de cada tarefa por máquina;
• Tem como objetivo minimizar o tempo de conclusão de todas as tarefas.
• Existem n! seqüências distintas possíveis.
O problema do sequenciamento pertence a classe NP-Dificil. Para a resolução do
problema utilizaremos a metaheuristica GRASP. Na Figura 1, podemos ver um exemplo do
problema, onde temos a matriz de tarefas e máquinas e partir dela devemos descobrir a melhor
sequência, ou seja, a sequência que nos dar o menor gasto de tempo. No exemplo a melhor
sequência (3,2,1) nos dar uma solução de 26.
2.6
Modelo Matemático do Problema
Na Figura 2 podemos ver o modelo matemático para esse problema, onde:
7. 6
Figura 1: Exemplos
• Tij – é o tempo de conclusão da Tarefa Jj na máquina Mi
• Pij – é o tempo de processamento da Tarefa Jj na máquina Mi
Figura 2: Modelo matemático
2.7
Calculo do Makespan
A Função objetivo é calculada segundo o seguinte pseudo-código:
1
2
3
input :
seq [] -> sequencia de tarefas ( solucao )
A [m , n] -> m numero de maquinas , numero de tarefas
8. 7
4
5
6
7
8
9
10
11
12
13
14
calc_makespan ()
T [1.. m] = 0 // vetor dos tempos das maquinas
para i = 1 ate n
k = seq [i]
T [1] = T [1] + A[k ][1]
para j = 1 ate m
se (T[ j] > T[j -1])
T [j] = T[ j] + A[ k ][ j ];
senao
T [j] = T[j -1] + A[k ][ j ];
retorne T[m ]
9. 8
3
SOLUÇÃO ADOTADA PARA O PROBLEMA DO SEQUENCIAMENTO
Nesse capitulo abordaremos a metaheuristica GRASP e a nossa implementação para a
resolução do problema.
3.1
Metaheuristica GRASP
A metaheuristica GRASP é constituída descrita primeiramente por (HART; SHOGAN,
1987) tem basicamente duas fases. Primeiramente temos a fase de construção, no qual construímos uma solução viável para o problema utilizando algumas técnicas de algoritmos gulosos
e aleatoriedade. Lembrando que nem sempre a solução construída nessa primeira fase, será
a ótima. Posteriormente temos a fase de busca local, que percorre a vizinhança da solução
corrente em busca de um ótimo local até que esse ótimo seja encontrado.
3.1.1
Fase de Construção
A fase de construção do GRASP tem por objetivo encontrar uma solução viável de
acordo com a implementação adotada. Para conseguir chegar nessa solução utiliza-se uma
metaheuristica semi-gulosa, pois, caso fosse inteiramente gulosa, o algoritmo iria encontrar
sempre a mesma solução na fase de construção, o que não é o objetivo.
Nessa fase devemos repetir o processo abaixo ate construirmos a solução:
• Para cada elemento candidato aplicar função gulosa nesse elemento;
• Armazenar os elementos em uma lista de candidatos;
• Selecionar os melhores candidatos e inseri-los em uma lista restrita LCR;
• Aplicar função aleatória para selecionarmos um elemento dessa lista restrita para fazer
parte da solução.
Observaçoes:
1. A função gulosa avalia o custo da incorporação do elemento na solução parcial.
2. A lista restrita LCR é construída com base na qualidade dos elementos. Obedecendo a
seguinte regra:
Em um problema de minimização:
10. 9
1
2
3
4
5
Cmin = menor elemento pendente
Cmax = maior elemento pendente ( pior )
LRC = { e pertencente a E / Ce <= Cmin + alpha .( Cmax - Cmin )
alpha = 0: guloso pura
alpha = 1: aleatorio pura
3.1.2
Fase de Busca Local
Na fase de busca local no algoritmo GRASP, primeiramente devemos definir a vizinhança local. A vizinhança é o conjunto de elementos que podemos gerar através de uma
modificação elementar feita em cima da solução passada. A busca local quase sempre melhora
a solução obtida na fase de construção, mas não necessariamente obtém o ótimo local.
A busca local ideal seria encontrar o ótico global através da solução inicial passada,
mas a situação mais real e provavel de ocorrer é de a busca encontrar apena o ótimo local.
3.2
Implementação
Para a resolução do problema do sequenciamento, implementamos o GRASP separando as duas fases, construção e busca local, que serão apresentadas nos subtópicos seguintes.
3.2.1
Fase de Construção
Nessa fase, executamos uma heuristica semi-gulosa para a escolha de cada elemento
constituinte da solução. No caso do problema do sequenciamento, uma solução possivel é uma
sequencia das tarefas que são executadas em cada máquina e que possuem um determinado
tempo de finalização, makespan. Como a solução deve ser construida por elemento( em nosso
caso os elementos são as tarefas ), criamos um laço do tamanho igual a quantidade de tarefas e
a cada iteração selecionamos uma tarefa para constituir a solução. A seleção ocorre da seguinte
maneira:
1. Cria-se uma lista de elementos candidatos. Essa lista é criada de forma gulosa, verificando sempre como será o impacto de escolher determinado elemento na solução. Em
nosso caso verificamos isso utilizando a função de calculo do makespan. Funcionando
da seguinte forma: na primeira interação calculamos o makespan para cada tarefa, ou
seja, calculando o makespan, considerando que há apenas a tarefa 1 ou 2, 3, ...n. Nessa
primeira interação teremos n candidatos para entrar na LRC. Digamos que por exemplo
a tarefa 2 tenha sido a escolhida, na próxima interação já iremos considerar duas tarefas,
ou seja, os conjuntos de candidatos para o LRC agora serão (2,1),(2,3),...(2,n). Assim
11. 10
teremos agora n-1 canditatos. o algoritmo segue até que a solução esteja completa com a
sequência com n tarefas.
2. Após definida a lista de candidatos, devemos selecionar os candidatos melhores ranqueados. Criando assim a lista restrita de candidatos LRC.
Nossa lista controlamos a entrada dos elementos com base nesses calculos:
1
2
3
4
5
6
7
8
Cmin -> menor makespan
Cmax -> maior makespan
LRC = { e -> indice que representa determinado elemento
pertencente a Lista de Candidatos , tal que
Ce <= Cmin + alpha .( Cmax - Cmin )}
alpha = 0: guloso pura
alpha = 1: aleatorio pura
O alpha que adotamos esta entre 0 e 1.
3. Após feita a LRC selecionamos randomicamente um elemento para constituir parte da
solução. Em nossa implementação utilizamos a função rand() com intervalo de 0 até N.
Sendo N a quantidade de elementos da LRC.
4. Escolhido o elemento para constituir a solução, automaticamente o mesmo na próxima
iteração não fará mais parte dos candidatos, pois ja esta na solução.
Esse processo é executado até que a solução seja completa.
O pseudocódigo dessa fase é mostrado abaixo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Elementos : E o conjunto de elementos que compoem a solucao
Canditatos : E o conjunto de elementos candidatos a entrar no LRC
LRC : Contem o conjunto de elementos de canditatos que atingiram
a condicao restrita
Solucao : Solucao final
Fase Construcao ()
Enquanto solucao incompleta Fazer
Candidatos = Elementos
LRC = c pertencente a Canditatos cuja
makespan (c ) <= makespan ( cmin ) + ( alpha * ( makespan ( cmax )
- makespan ( cmin )))
se LRC nao esta vazio
elemento = Um elemento de LRC escolhido aleatoriamente
senao
12. 11
17
elemento = o elemento cmax
18
Incluir elemento na Solucao
19
Retira elemento de Elementos
20
Fim
21
Retorna Solucao
22 Fim Fase Construcao
3.2.2
Fase de Busca Local
Para busca local foi implementado um algoritmo simples que troca de posição apenas
um elemento por vez(assim dois elementos trocam de posição). A troca de posição(pertubação)
é feita conforme a função abaixo:
1
2
3
4
5
6
7
8
pos : posicao que sera trocada
sol : solucao que sera pertubada
n_elementos : n_elementos da solucao
disturbing ()
pos_de_troca = pos
enquanto pos igual pos_de_troca
pos_de_troca = rand () mod n_elementos
troca ( sol [ pos ], sol [ pos_de_troca ])
onde pos varia da posição 1 até n. No algoritmo pegamos o melhor vizinho dentre todos os n gerados usando essa função de pertubação. Foi um criado um parâmetro chamado depth(profundidade),
onde indica quantas vezes iremos repetir esse processo na busca local, por exemplo se tivermos
depth = 2, a melhor solução encontrada na primeira busca, será a inicial na segunda. O pseudocódigo da busca local segue abaixo:
1
2
3
4
5
6
7
8
9
10
11
depth : profundidade da busca
busca_local ()
melhor_solucao = solucao_corrente // solucao calculada
// no metodo guloso
para k = 0 ate k = depth
para i = 0 ate i = num_tarefas
vizinho = disturbing (i , solucao_correte , num_tarefas )
se vizinho e melhor que melhor_solucao
melhor_solucao = vizinho
solucao_corrente = melhor_solucao
retorne melhor_solucao
essa melhor solução é a solução final da nossa metaheurística.
13. 12
4
RESULTADOS
Para fazer o análise da metaheurística, variamos os parâmetros α e depth da seguinte
forma: α = (0, 0.5, 1.0) que são valores com guloso puro, meio termo entre guloso e aleatório
e puramente aleatório e depth = 100 que nos realiza uma boa busca local, para cada par (α,
depth) realizamos 30 testes, e assim podendo ser retirados a média do tempo de execução, a
média das soluções e a melhor solução obtida entre os 30 testes. Os resultados podem ser vistos
nas tabelas abaixo(Observação em Inicial(Me, Max), indica a solução inicial da melhor solução
e da máxima respectivamente):
α = 0.0, depth = 100
Instâncias Comparativas
Referência
Solução
m
n
Ótima
abz5
10
10
===
Car5
10
6
7720
Solução Obtida
Inicial
Aproximação
tempo(milis)
Melhor Gap
1650
3.072278
1538
===
10152
1.806426
7786
66
Media das aproximacões com resultados desconhecidos
Referência
m
n
Inicial(Me,Max) Máxima
Média
————–
Melhor tempo(milis)
Hel11
100
10
(656, 658)
534
527.333333
523
252.126129
ReC07
20
10
(2154, 2198)
1697
1670.666667
1595
11.002906
Rec13
20
15
(2490, 2490)
2090
2017.533333
2374
17.397634
Rec41
75
20
(6438, 6652)
5486
5389.966667
5255
311.971744
α = 0.5, depth = 100
Instâncias Comparativas
Referência
Solução
m
n
Ótima
abz5
10
10
===
Car5
10
6
7720
Solução Obtida
Inicial
Aproximação
tempo(milis)
Melhor Gap
1634
2.723050
1538
===
9023
1.677171
7720
0
Media das aproximacões com resultados desconhecidos
Referência
m
n
Inicial(Me,Max) Máxima
Média
————–
Melhor tempo(milis)
Hel11
100
10
(619, 637)
536
529.166667
523
245.505182
ReC07
20
10
(1985, 2144)
1712
1650.966667
1584
10.824156
Rec13
20
15
(2372, 2503)
2110
2030.800000
1955
17.017579
Rec41
75
20
(6438, 6652)
5473
5401.233333
5306
312.249899
α = 1.0, depth = 100
14. 13
Instâncias Comparativas
Referência
Solução
m
n
Ótima
abz5
10
10
===
Car5
10
6
7720
Solução Obtida
Inicial
Aproximação
tempo(milis)
Melhor Gap
1591
2.752074
1538
===
8538
1.835267
7738
18
Media das aproximacões com resultados desconhecidos
Referência
m
n
Inicial(Me,Max) Máxima
Média
————–
Melhor tempo(milis)
Hel11
100
10
(572, 576)
536
528.966667
524
245.887979
ReC07
20
10
(1786, 2051)
1726
1665.666667
1595
11.118690
Rec13
20
15
(2237, 2483)
2089
2021.766667
1968
16.956004
Rec41
75
20
(6128, 6610)
5505
5392.000000
5275
311.869550
Podemos observar que o valor de α afeta diretamente as soluções inicias geradas, pois
esta ligada a fase construção com uso de um algoritmo guloso. Quando aumentamos o α de
0 para 0.5,1.0 percebemos que os valores algumas vezes melhoram outras vezes pioram, isso
se deve a aleatoriedade do processo, pois a medida que o valor de α aumenta a escolha na
fase construção fica mais aleatória. Na hora gerar os resultados finais, percebemos que mesmo
mudando as soluções inicias os resultados das soluções finais nas 3 tabelas ficaram muito próximos.
15. 14
5
CONCLUSÃO
Várias abordagens podem ser feitas para o problema do sequenciamento, neste trabalho mostramos um deles usando a metaheurística grasp que é muito simples, bastando ter em
mãos um bom algoritmo guloso e de busca local, os resultados nos mostrou que conseguimos
atingir no caso da entrada Car5 a solução ótima. outras estratégias podem ser usadas na fase
de construção ou de busca local, ou ainda encontrar um melhor valor para α, nesse trabalho
avaliamos os casos extremos e o do meio(0,0.5,1.0), é provável outro valor intermediário posso
obter melhores resultados e até mesmo alcança a solução ótima para mais casos.
16. 15
BIBLIOGRAFIA
CUNHA, Claudio Barbieri da. Um modelo matemático para o problema de seqüenciamento e
programação de visitas de gerentes de banco. SciELO Brasil, 2003.
HART, J Pirie; SHOGAN, Andrew W. Semi-greedy heuristics: An empirical study. Operations
Research Letters, Elsevier, v. 6, n. 3, p. 107–114, 1987.
MÜLLER, Felipe Martins; LIMBERGER, Sergio João. Uma heurística de trocas para o problema de sequenciamento de tarefas em processadores uniformes. Pesquisa Operacional, SciELO Brasil, v. 20, n. 1, p. 31–42, 2000.