• Aucun résultat trouvé

Quatro otimizadores foram implementados para o problema de produção de recursos com eventos cíclicos e comparados em um experimento computacional: (a) NSGA-II (DEB

et al., 2002), (b) uma versão do NSGA-II com um algoritmo de ordenação baseado nos

ângulos entre as soluções (BRANKE et al., 2004), (c) uma colônia de formigas multiob-

jetivo, ou MOACO (LÓPEZ-IBÁÑEZ, 2004) e (d) GRASP multiobjetivo, ou MOGRASP

(REYNOLDS; CORNE; IGLESIA, 2009). Embora seja possível encontrar as soluções ótimas

através de um algoritmo exato, otimizadores heurísticos foram escolhidos pelo tempo que os algoritmos exatos consomem, tornando-os inviáveis para uso em um cenário real para inteligências articiais de jogos. Neste capítulo, as versões usadas nos experimentos serão explicadas.

Todos os algoritmos utilizados possuem uma forma de paralelismo. Nos algoritmos genéticos, esse paralelismo se dá na criação e mutação das soluções, no MOACO e MO- GRASP na criação de soluções e na busca local. Este paralelismo foi utilizado para acessar todo o poder de processamento de modernas CPU que possuem mais de um núcleo pro- cessador.

Além disto, todos os algoritmos utilizam uma única operação de vizinhança: a simples troca de posição entre duas tarefas aleatórias diferentes de uma solução, o que pode resultar em uma solução inválida. Caso a nova solução seja inválida, uma operação de conserto é utilizada até que uma solução válida seja encontrada, baseada no algoritmo de criação de solução aplicado à metaheurística.

5.1 NSGA-II

Dois algoritmos genéticos foram implementados, ambos baseados numa simplicação da meta-heurística NSGA-II. Estas versões diferem apenas no funcionamento do método de ordenação, avaliar_ordenar, onde foram usados o método original baseado em distância entre soluções e um método alternativo baseado nos ângulos entre as soluções do conjunto

Algoritmo 5 NSGA-II Simplicado

1: procedimento NSGAII(I0, O, δo, δr, ∆o, ∆r, c, δoF, δrF, ∆Fo, ∆Fr, it)

2: x ←gerarParalelo(c, δo, δr, ∆o, ∆r)

3: avaliar_ordenar(x, O)

4: para i = 1 até it faça

5: x ← selecionar(x)

6: ˙x ← ∅

7: para todo s ∈ x em paralelo faça

8: ˙x ← ˙x ∪ mutar(s, δoF, δrF, ∆Fo, ∆Fr) 9: m para 10: x ← x ∪ ˙x 11: avaliar_ordenar(x, O) 12: m para 13: m procedimento

de aproximação. A operação de seleção, selecionar, é a mesma para os dois casos, isto é, a partir de uma população com o dobro do tamanho permitido L, seleciona-se as melhores L soluções. Em ambos os casos, a operação de mutação é uma simples troca de posição entre duas tarefas.

O algoritmo base (ver Algoritmo 5) recebe como entrada o estado inicial I0, a estratégia

O, os valores de contribuição δo, δr e os valores de incremento ∆o, ∆r para o algoritmo

de criação, o tamanho n do arquivador, os valores δF

o, δFr, ∆Fo, ∆Fr para o algoritmo de

reconstrução, além da quantidade de iterações it. Inicialmente são geradas aleatoriamente as soluções, e então o algoritmo as avalia e ordena. Dentro do laço iterativo, o algoritmo seleciona as soluções do conjunto, seguindo a seleção do NSGA-II em que as N melhores soluções são selecionadas de acordo com o algoritmo de ordenação, onde N é o tamanho do arquivador. A implementação utilizada para o NSGA-II não possui um operador de cruzamento nem uma chance de mutação. Ao invés disto, novas gerações são criadas a partir de todas as soluções do conjunto atual através de uma simples mutação. Finalmente, o conjunto de soluções é avaliado e ordenado no m do laço. Para acelerar o desempenho do algoritmo, a criação e a mutação das soluções são feitas em paralelo.

5.1.1 Knee

Em seu trabalho sobre a busca de joelhos em otimização multiobjetivo, Branke et al. (2004) apresentaram duas abordagens para o otimizador: (a) otimizador focado em ângulo e (b) otimizador focado em utilidade. Estas alterações se dão como substituição do algoritmo de ordenação do NSGA-II, crowding distance. Os experimentos feitos aqui mostraram resultados para o otimizador focado em ângulo. Esta abordagem verica o

Algoritmo 6 Algoritmo de ordenação baseada em ângulos

1: procedimento KneeSort(x, O)

2: x0 ← ordenarNaoDominado(x, O) . Mesma ordenação usada no NSGA-II

3: para todo I ∈ x0 faça

4: metrica ← {0, . . . , 0}

5: para todo m ∈ M ∪ N faça

6: ordernarDescendente(I, m) . Ordena pelo objetivo m

7: metrica[I[1]] ← metrica[I[|I|]] ← ∞ .Valores extremos são selecionados

8: m para

9: para i = 2 até |I| − 1 em paralelo faça

10: se metrica[i] = 0 então

11: A ← {v ∈ I| 6 ∃v0 ∈ I \ {I[1], I[|I|], I[i]}, ||v0− i|| < ||v − i||}

12: B ← {v ∈ I|Ortante(v − I[i]) 6= Ortante(A − I[i])}

13: B ← {v ∈ B| 6 ∃v0 ∈ I \ {I[1], I[|I|], I[i], A}, ||v0− i|| < ||v − i||}

14: A ← A − i 15: B ← B − i 16: metrica[i] ← 2π − arccos  A·B ||A||||B||  17: m se 18: m para 19: ordernarDescendente(I, metrica) 20: m para 21: m procedimento

ângulo que existe entre dois pontos e um determinado eixo. Essa comparação é feita usando cada um dos pontos como eixo.

Inicialmente, o algoritmo de ordenação (ver algoritmo 6) classica as soluções de acordo com o seu grau de dominância, utilizando o mesmo método do NSGA-II. Estas soluções estão divididas em conjuntos de forma que cada conjunto domine todos os se- guintes. Então, para cada conjunto I serão calculados valores para cada solução, referentes à métrica de ordenação. Os valores são inicializados em zero, e os pontos extremos para cada função objetivo recebem o valor innito, para que eles sejam sempre selecionados. Os demais pontos utilizarão o ângulo entre os pontos mais próximos que não estão no mesmo ortante em relação ao eixo i. Isto é feito selecionando o ponto mais próximo da solução i, e o segundo ponto mais próximo de i que não esteja no mesmo ortante que o anterior.

5.2 MOGRASP

A versão multiobjetivo do GRASP utilizada neste trabalho (algoritmo 7) utiliza con- juntos de aproximação ao invés de soluções, tanto para o algoritmo de criação quanto

Algoritmo 7 GRASP multiobjetivo

1: procedimento MOGRASP(I0, O, δo, δr, ∆o, ∆r, c, n, δoF, δrF, ∆Fo, ∆Fr, it)

2: x∗ ← ∅

3: para i = 1 até it faça

4: ˙x ← gerarParalelo(c, δo, δr, ∆o, ∆r) 5: x∗ ← x ∗ ∪ ˙x 6: x∗ ← {x0 ∈ x ∗ | 6 ∃xi ∈ x∗, xi  x0} 7: x∗ ← buscaLocal(x∗, n, δF o, δrF, ∆Fo, ∆Fr) 8: x∗ ← {x0 ∈ x ∗ | 6 ∃xi ∈ x∗, xi  x0} 9: m para 10: retorne x∗ 11: m procedimento

para o algoritmo de busca local. A cada iteração, o algoritmo gera c novas soluções pa- ralelamente, usando o mesmo processo de criação que o NSGA-II. Essas soluções são adicionadas ao conjunto de aproximação e as soluções não-dominadas são ltradas. En- tão, um algoritmo de busca local baseado em conjuntos inicia sua busca a partir deste conjunto, e as soluções encontradas são colocadas no conjunto de aproximação e ltradas. O algoritmo 7 utiliza a busca local baseada em conjuntos (BASSEUR et al., 2013),

onde a busca local trabalha em conjuntos de soluções ao invés de soluções individuais. A relação de vizinhança utilizada foi N(?,?), uma vez que um número n de vizinhos é

calculado para cada solução do conjunto atual. A operação de vizinhança usada foi uma simples troca entre duas tarefas. O algoritmo de conserto de soluções é aplicado após a operação de vizinhança, caso a solução nal seja inválida. Como o algoritmo de conserto possui necessidades diferentes das necessidades do algoritmo de criação, pesos diferentes são passados para cada um deles. Estes pesos são δF

o , δrF, ∆Fo e ∆Fr.

Para encontrar a melhor fronteira de aproximação, o MOGRASP utilizou uma ver- são paralela do arquivador de grade adaptativa, ou Adaptive Grid Archiver (KNOWLES;

CORNE, 2003). Esta versão utiliza threads diferentes para selecionar os vetores unicamente

extremos e para calcular os limites do hipercubo.

5.3 MOACO

Os otimizadores descritos até agora utilizaram o método de criação de soluções mos- trado no capítulo anterior. Para usar um algoritmo baseado em formigas, um novo al- goritmo de criação é proposto, que se baseia em um grafo que conecta todas as tarefas entre si e com um outro vértice que aponta para o início da solução (veja Figura 6). Este

Algoritmo 8 Criação de soluções através de formigas

1: procedimento criarFormiga(I0, O, δo, δr, ∆o, ∆r, τ, α, β)

2: x ← ∅

3: r ← 1

4: enquanto não valido(x) faça

5: η ← pesosIniciais(δo, δr, I0, O)

6: δo ← δo∆o

7: δr ← δr∆r

8: x ← x ∪ escolhaFormiga(τ, η, α, β)

9: se Smax(x) > U B então .Caso a última tarefa seja inválida

10: tamanho ← x.tamanho

11: x.redimensionar(tamanho − r) .Reduz o tamanho da solução

12: r ← r + 1 13: se r > x.tamanho então 14: r ← 1 15: m se 16: m se 17: m enquanto 18: retorne x 19: m procedimento

grafo indica os passos que uma formiga tomaria para chegar à última tarefa. Para aplicar a criação de formigas ao problema de produção de recursos, o algoritmo de criação, ex- posto no algoritmo 8, utiliza um único tipo de feromônio (LÓPEZ-IBÁÑEZ, 2004). Assim,

um grafo deste tipo é utilizado para guardar as informações dos feromônios, enquanto as informações heurísticas não dependeriam da última tarefa escolhida.

O algoritmo de criação recebe como entrada o estado inicial I0, a estratégia O, os

pesos e multiplicadores δo, δr, ∆o, ∆r, a taxa de evaporação τ, a inuência dos feromônios

α e a inuência da heurística β. A partir de uma solução vazia, o algoritmo escolhe uma tarefa baseado nos pesos iniciais e nos feromônios deixados por formigas anteriores. O algoritmo 8 utiliza informações heurísticas e de feromônio da mesma maneira que o Ant

S start

T0

T1

T2

Algoritmo 9 Colônia de formigas multiobjetivo

1: procedimento MOACO(I0, O, δo, δr, ∆o, ∆r, ρ, α, β, n, δFo, δrF, ∆Fo, ∆Fr, formigas,

it)

2: x∗ ← ∅

3: inicializar(τ)

4: para i = 1 até it faça

5: ˙x ← ∅

6: para f ∈ formigas em paralelo faça

7: x ← criarFormiga(I0, O, δo, δr, ∆o, ∆r, τ, α, β) 8: x ← buscaLocal(x, n, δF o, δFr, ∆Fo, ∆Fr) 9: ˙x ← ˙x ∪ x 10: m para 11: x∗ ← x∗ ∪ ˙x 12: x∗ ← {x0 ∈ x ∗ | 6 ∃xi ∈ x∗, xi  x0} 13: atualizar(τ, ρ) 14: m para 15: retorne x∗ 16: m procedimento

System, como na equação 7.1. pij(t) =

[τij(t)]α[ηij]β

P

k[τik(t)]α[ηik]β

(5.1) Como este problema possui um ou mais objetivos, o feromônio reete a sequência de tarefas em cada solução da fronteira de aproximação atual. A cada iteração, o feromônio τij(t) é igual ao número total de transições da tarefa i para a tarefa j em cada solução

da fronteira no tempo t − 1. A informação heurística reete os pesos dados pela função initialW eightsdescrita no capítulo 6, que não requer uma sequência de tarefas.

O algoritmo continua escolhendo até que a solução seja válida ou que uma tarefa seja alocada num tempo superior ao horizonte do projeto. Neste caso, ele retira uma quantidade de tarefas incremental do m da solução e continua a alocar mais tarefas. A cada iteração, os valores dos pesos são aumentados pelas taxas ∆o e ∆r, o que direciona

as escolhas da formiga.

O algoritmo de busca local utilizado é o mesmo usado pelo MOGRASP, usando a mesma relação de vizinhança N(?,?). O arquivador utilizado pelo foi o arquivador de grade

adaptativa, ou Adaptive Grid Archiver, na versão paralela utilizada pelo MOGRASP. Uma vez que a execução de uma formiga não interfere nos resultados das outras formigas da mesma iteração, cada formiga pode ser executada em processos paralelos

uma varredura na vizinhança de cada formiga, também em paralelo: há uma thread di- ferente para cada vizinho de cada solução do conjunto. Desta forma, todas as soluções vizinhas do conjunto atual são visitadas paralelamente a cada iteração.