• Nenhum resultado encontrado

Assim como foi feito para as outras meta-heurísticas, o SA também será implementado para o PMM. E, como nos casos anteriores, o código-fonte da importação dos dados e do cálculo da FO poderão ser reutilizados. O código-fonte do programa principal vai precisar apenas de alguns pequenos ajustes. O Simulated Annealing, em sua primeira versão, não faz uso de nenhuma outra função acessória, como uma busca local, de forma que, será preciso implementar apenas a meta-heurística. Para isso, siga os passos:

Passos

1. Copie o código-fonte disponibilizado a seguir;

2. Cole o código em um editor de textos de sua preferência;

3. Salve o arquivo com o nome: SimulatedAnnealing.py na pasta

C:\AulaPython.

1 import time

2 import math as mat 3 import copy as cpy 4 import random as rand 5 import calcFO as CF 6

7 #gerando a semente

8 rand.seed() 9

10 def SimulatedAnnealing(samax, ti, tc, tx, solIni, numObj, numMoc, vetValObj, vetPesObj, vetCapMoc):

11 ini = time.time() 12 achouT = time.time()

13 #guarda a solucao inicial como a melhor

14 mSol = solIni

15 mFO = CF.calcFO(mSol, numObj, numMoc, vetValObj, vetPesObj, vetCapMoc)

16 #atribui a melhor solucao a sol atual

17 sol = cpy.copy(mSol)

18 FO = CF.calcFO(sol, numObj, numMoc, vetValObj, vetPesObj, vetCapMoc)

19 #inicializa a temperatura

20 temp = ti

21 while temp > tc:

22 #enquanto a temperatura inicial e maior que a temp de congelamento

23 for i in range(samax):

24 #solucao vizinha inicia a partir da solucao atual

25 vSol = cpy.copy(sol)

26 #sorteia uma solucao vizinha

27 vSol[rand.randint(0, numObj-1)] = rand.randint(0, numMoc)

28 #calcula a FO da solucao vizinha

29 vFO = CF.calcFO(vSol, numObj, numMoc, vetValObj, vetPesObj, vetCapMoc )

30 #calculando a variacao

31 delta = FO - vFO

32

33 if delta < 0:

Aula 12. Meta-heurística Simulated Annealing 168

35 sol = cpy.copy(vSol)

36 if vFO > mFO:

37 #se a FO da vizinha e melhor que a FO da FO global aceita

38 mSol = cpy.copy(vSol)

39 achouT = time.time()

40 else:

41 if rand.random() < mat.exp(-(FO - vFO) / temp):

42 #se nao e melhor mas aceita piorar

43 sol = cpy.copy(vSol)

44

45 #resfria a temperatura

46 temp *= tx

47

48 return mSol, (achouT - ini)

Entre as linhas 1 e 5 foi realizada a importação das bibliotecas necessárias para a meta-heurística. Na linha 8 foi gerada a semente aleatória, conforme as orientações da aula7. Na linha 10 inicia a função, cujos argumentos de entrada são: samax referente ao número de iterações, ti para temperatura inicial, tc para temperatura de congelamento,

tx para taxa de resfriamento, solIni para solução inicial e os demais argumentos do

PMM. As variáveis são inicializadas entre as linhas 11 e 20, como a inicialização da melhor solução global na linha 14, da solução corrente na linha 17 e da temperatura corrente na linha 20. O laço externo inicia na linha 21, observe que a condição de manutenção do laço é exatamente igual ao do código base já visto e para garantir que o laço termine quando a temperatura se aproximar da temperatura de congelamento, foi incluída a instrução da linha 46 que é responsável por resfriar a temperatura corrente, com base na taxa de resfriamento.

O laço interno na linha 23 vai garantir as iterações que irão buscar o equilíbrio térmico para cada temperatura avaliada no laço externo. Na linha 25 é inicializada a solução vizinha com a solução corrente, na linha 27 são realizados dois sorteios, o primeiro do objeto, ou seja, aleatoriamente é escolhido um objeto para trocá-lo de mochila, que é o segundo sorteio. Após realizar o sorteio, é feito o cálculo da FO da solução vizinha, conforme a instrução na linha 29, como já temos a FO da solução corrente, então é realizado o cálculo da variação na linha 31. Na linha 33 é verificado se a variação é negativa, pois se essa condição for verdadeira, então a solução será aceita na instrução da linha 35. Se a solução vizinha também for melhor que a solução global, então a solução global é ajustada conforme a linha 38.

Se a variação for positiva ou nula, então temos a situação em que a solução vizinha é pior ou igual, neste caso é realizada a validação da linha 41, seguindo as definições do código base, e em caso verdadeiro a solução será aceita na linha 43. Após finalizar as iterações do laço externo, ou seja, após a temperatura resfriar e atingir a temperatura de congelamento, a solução é retornada ao método que a invocou, conforme a instrução da linha 48. Realize os passos a seguir para testar o SA implementado.

Passos

1. Copie o código-fonte disponibilizado a seguir;

2. Abra o arquivo prgMain.py presente na pasta C:\AulaPython; 3. Cole o código substituindo o código atual do arquivo;

Aula 12. Meta-heurística Simulated Annealing 169

1 import leDados as LD 2 import calcFO as CF

3 import SimulatedAnnealing as SA 4 import heuConAle as HCA

5

6 numObjetos = numMochilas = 0 7 vetValoresObjetos = [] 8 vetPesosObjetos = [] 9 vetCapacidadeMochilas = []

10 numObjetos, numMochilas, vetValoresObjetos, vetPesosObjetos, vetCapacidadeMochilas = LD.leDados()

11

12 solIni = HCA.heuConstrutivaAleatoria(numObjetos, numMochilas) 13

14 samax = ((numMochilas + 1) * numObjetos) * 1 15 tempInicial = 100

16 tempCongelamento = 0.01 17 txResfriamento = 0.975 18

19 #obtendo uma solucao pela meta-heuristica Simulated annealing

20 sol, tempo = SA.SimulatedAnnealing(samax, tempInicial, tempCongelamento, txResfriamento, solIni, numObjetos, numMochilas, vetValoresObjetos, vetPesosObjetos, vetCapacidadeMochilas)

21

22 #calculando a FO da solucao obtida

23 FO = CF.calcFO(sol, numObjetos, numMochilas, vetValoresObjetos, vetPesosObjetos, vetCapacidadeMochilas)

24

25 print "Solucao: ", sol 26 print "FO: ", FO

27 print "Achou em: %.2f " % tempo

Conforme pode ser visto no código-fonte do programa principal, foram realizadas poucas adaptações, a primeira é a linha 3 do código com a importação do arquivo de fonte da função do Simulated Annealing. O segundo ajuste refere-se à configuração dos parâmetros do SA, entre as linhas 14 e 17, em que samax foi definido conforme o número de mochilas e objetos para possibilitar que este tamanho possa se adaptar conforme os dados. tempInicial foi configurado com o valor 100, tempCongelamento foi configurado como 0.01 e txResfriamento com 0.975. Na próxima seção abordamos com mais detalhes sobre a calibração destes parâmetros. O terceiro e último ajuste é a invocação da função responsável por executar a meta-heurística, na linha 20. O restante do código permaneceu inalterado. Agora é possível testar a meta-heurística SA, para executar abra o interpretador do Python e execute o programa principal, conforme o trecho a seguir.

1 >>> runfile('C:/AulaPython/prgMain.py', wdir='C:/AulaPython')

2 Solucao: [1, 3, 3, 1, 1, 1, 1, 2, 3, 3, 2, 0, 3, 3, 0, 0, 2, 1, 0, 3] 3 FO: 9418

4 Achou em: 0.24

Como pode ser visto, no teste realizado para este livro, a FO da "melhor solu-ção"obtida pelo Simulated Annealing, é 9.418 e esta solução foi encontrada em 0.24 segundos. Tudo indica que os parâmetros configurados permitiram uma execução

Aula 12. Meta-heurística Simulated Annealing 170

muito rápida, talvez, por isso, o SA não tenha conseguido uma solução com qualidade melhor. A próxima seção tratará sobre a calibração dos parâmetros, que neste caso, poderá melhorar os resultados do SA.

12.5 Calibração dos parâmetros

O Simulated Annealing possui 4 parâmetros que irão influenciar no seu desempenho em termos de tempo de processamento e eficácia em obter boas soluções. Além disso, estes parâmetros estão relacionados entre si, de forma que, um pode afetar o outro. A temperatura inicial, representada no código base por T0, está associada ao número de estados que o Simulated Annealing vai produzir até atingir a temperatura de con-gelamento, assim, se colocar uma temperatura muito baixa, é provável que o SA faça poucas iterações e obtenha poucos estados térmicos, consequentemente. De forma que, para alguns problemas, é possível que temperaturas iniciais baixas não sejam suficientes para produzir boas soluções. Por outro lado, se calibrar o método com uma temperatura muito alta, é provável que o SA tenha um desempenho ruim em termos de tempo de processamento, deve-se então equilibrar a temperatura inicial de acordo com o problema. Um entendimento sobre a T0é que ela deve ser alta o bastante para permitir movimentos livres entre soluções vizinhas.

Ainda há outro aspecto que deve ser considerado, pois a temperatura inicial é afetada pela temperatura de congelamento, representada no código base pelo Tc, de forma que, não adianta iniciar o SA com uma temperatura muito alta e ao mesmo tempo calibrar a temperatura de congelamento, também com um valor muito alto, ou próximo da temperatura inicial, pois assim, a eficácia em produzir estados térmicos, provavelmente será ruim. Desta forma, é muito comum calibrarmos a temperatura de congelamento com valores muito próximos de zero, como: 0,01, 0,001, etc. Até mesmo para que se assemelhe à temperatura natural de congelamento. Tendo a temperatura de congelamento sempre como próxima de zero, então o desafio será sempre encontrar a melhor temperatura para inicializar o SA.

Como já mencionado, os parâmetros exercem influência uns sobre os outros, e a taxa de resfriamento, representada peloα, também influencia na temperatura inicial,

pois dependendo da taxa de resfriamento a temperatura pode diminuir rápido ou devagar. Este parâmetro deve ser configurado sempre com valores maiores que 0 e menores que 1, ou seja, (0 < α < 1). No geral, se queremos um resfriamento lento, então devemos configurar na faixa (0.8 < α < 0.99), se desejamos um resfriamento mais rápido então podemos adotar a faixa (0 < α < 0.8). Uma sugestão é que este parâmetro seja calibrado com o valor 0.975 ou 0.995.

O quarto parâmetro, número de iterações, representado por SAMax, influencia no equilíbrio térmico que deve ser atingido em cada temperatura que é avaliada pelo SA, durante o processamento. Assim, um valor para SAMax muito pequeno pode dificultar o SA a atingir o equilíbrio térmico, por outro lado, um número muito grande também não traria muitos benefícios, podendo afetar no desempenho, desta forma, é comum que este parâmetro seja calculado com base na dimensão do problema, como foi feito para o PMM, neste livro.

Em resumo, a melhor forma de calibrar os parâmetros é por meio de testes e ava-liação dos resultados. Uma boa estratégia é contabilizar e imprimir um resumo de várias informações ao longo dos testes, por exemplo, contabilizar o número de vizinhos gerados e aceitos, se o número de vizinhos aceitos for alto em relação ao número de vizinhos gerados, isso é um bom indicador.

Aula 12. Meta-heurística Simulated Annealing 171