PESQUISA OPERACIONAL TRABALHO PROBLEMA DE TRANSPORTE
OBJETIVO Implementação de uma heurística utilizando Algoritmo Genético para resolver um problema de transporte e comparar com a busca aleatória utilizando como parâmetros estatísticos a média, desvio e teste t.
DESCRIÇÃO O trabalho envolve a resolução por meio de um Algoritmo Genético e através de busca aleatória. O problema de transporte corresponde a um problema de programação linear que trata do envio de produtos das fábricas f ábricas (centros produtores) para depósitos (centros consumidores). O objetivo desta programação linear é minimizar o custo total do caminho percorrido e satisfazer as restrições de fornecimento fo rnecimento e demanda. As restrições importantes a serem obedecidas são que as fábricas não podem produzir mais do que suas capacidades instaladas e os centros consumidores não desejam receber produtos acima de suas demandas. O processo utilizado foi o caminho de execução tradicional de um Algoritmo Genético: (1) gera um população inicial; (2) avalia cada indivíduo da população; (3) enquanto critério de parada não for satisfeito: (3.1) selecionar os indivíduos mais aptos (3.2) criar novos indivíduos aplicando os operadores crossover e mutação (3.3) armazenar os novos indivíduos em uma nova população (3.4) avaliar cada indivíduo da nova população. Foi utilizado o Algoritmo Genético para minimização do problema de transporte, pois este tem a capacidade de manter uma população de indivíduos que podem ser possíveis soluções para o problema de transporte. O algoritmo busca as soluções através de mecanismos da seleção natural e genética (cruzamento e mutação) onde os indivíduos (soluções) que não minimizarem o custo do problema tenderão aos poucos a desaparecer.
O problema hipotético a ser resolvido pelo Algoritmo Genético e pela busca aleatória foi o seguinte: A EMATT é uma empresa responsável pelo transporte terrestre de cargas de soja do Estado do Maranhão que possuí possuí cinco polos produtores localizados em Carolina, Balsas, Colinas, Matões e Tutóia. A produção da empresa deve ser entregue em São Luís, Imperatriz, Pinheiro, Caxias e Chapadinha. Considerando os custos de transporte unitários, a capacidade de produção dos polos (em toneladas) e a demanda dos centros consumidores ilustrados na tabela abaixo, determine quanto deve ser produzido e entregue por polo em cada centro consumidor, consumidor, de forma a minimizar os custos de transporte. Polo / Centro Consumidor Carolina Balsas Colinas Demanda
São Luís
Imperatriz
Pinheiro
Capacidade
50 40 25 2500
10 20 25 2000
40 40 25 1500
3000 2500 1500
ESTRUTURAS DO PROBLEMA Min Z = 50X 11 + 10X12 + 40X13 + 40X21 + 20X22 + 40X23 + 25X31 + 25X32+ 25X33 Restrições de Oferta (as fábricas não podem produzir mais do que suas capacidades)
X11 + X12 + X13 <= 3000
Restrições de Demanda (os centros consumidores não desejam receber volumes acima de suas demandas) X11 + X21 + X31 = 2500
X21 + X22 + X23 <= 2500
X12 + X22 + X32 = 2000
X31 + X32+ X33 <=1500
X13 + X23 + X33 = 1500
Restrições de Não-negatividade
Xij >= 0, para i=1,2,3 e j=1,2,3
PARTES DO PROJETO A codificação do projeto foi realizada com a linguagem de programação Java utilizando a IDE Eclipse. O projeto foi desenvolvido a partir de dois pacotes: alg_genetico e alg_genetico e busca_aleatoria. busca_aleatoria.
No pacote alg_genetico há quatro classes onde ocorre todo o processamento do algoritmo genético: Principal, Indivíduo, População e Algoritmo. No pacote busca_aleatoria há uma classe onde ocorre o processamento p rocessamento da busca aleatória.
PROCESSO A classe Principal classe Principal inicia inicia toda a execução e são s ão definidos o tamanho da população, a quantidade de genes, a taxa de cruzamento, a taxa taxa de mutação, a quantidade da geração e a escolha do elitismo. A classe Individuo classe Individuo é é uma das classes principais do programa. Ela que representa o conjunto de valores que serão ou não a solução para o problema. Neste trabalho, a representação do indivíduo é dado através de um vetor v etor de inteiros com 9 (nove) posições. A classe consta de dois construtores: Individuo(int) para Individuo(int) para gerar com indivíduos aleatórios que comporão a população inicial e Indivíduos(int e Indivíduos(int []) para []) para gerar indivíduos com genes definidos para as demais populações. Neste último construtor que acontece o processo mutação. Vale ressaltar que quando os indivíduos são criados a partir do primeiro construtor, os valores que farão parte dos genes obedecem as restrições de demanda de forma que qualquer indivíduo seja sempre válido. O segundo construtor auxilia a classe Algoritmo no processo de mutação gerando indivíduos a partir de genes predefinidos e que obedeçam as também as restrições de demanda a partir do método balanceamento().A balanceamento().A importância deste método no programa é possibilitar que a mutação gere um indivíduo diferente mas que não infrinja as restrições de demanda embora sua aptidão seja maior ou menor do que o indivíduo de origem. Na classe Individuo classe Individuo há há também o método geraAptidao() método geraAptidao() que que gera um valor a partir da função objetivo com base nos genes do individuo. Esse método auxilia a classe Populacao classe Populacao quando quando esta precisa ser ordenada de forma crescente ao resultado da função objetivo. A classe Populacao Populacao tem a função de representar o conjunto de indivíduos que podem ser a solução do problema. Tem dois atributos principais: tamPopulacao, tamPopulacao, o tamanho da população, e indivíduos, indivíduos, que são os conjuntos de vetores que armazenam os valores de uma u ma possível solução. Esta classe tem dois contrutores: Populacao(int contrutores: Populacao(int numGenes, int tamPop), tamPop) , que cria uma população com indivíduos aleatórios,e Populacao(int aleatórios,e Populacao(int tamPop), tamPop), que cria uma população com indivíduos sem nenhum valor armazenado. Este segundo
construtor é utilizado quando se quer criar uma nova geração onde primeiro cria-se os indivíduos sem valor algum e depois d epois é que estes recebem rec ebem valores a partir da população anterior. Esta classe tem os métodos ordenaPopulacao(), ordenaPopulacao(), que ordena a população levando em consideração a aptidão, getNumIndividuos(), getNumIndividuos(), que retorna a quantidade de indivíduos que armazenam algum valor e verrestricao(), que verifica se um indivíduo ao ser criado obedece as restrições do problema de transporte. A classe Algoritmo tem a função de realizar o processo de criar uma nova geração, efetuar a operação de crossover, mutação e seleção respectivamente representados pelos métodos novaGeracao(Populacao populacao, boolean elitismo), selecaoTorneio(Populacao populacao) e crossover(Individuo individuo1, Individuo individuo2). No método novaGeracao() acontece o processo de evolução onde a nova população é construída através da população anterior depois de realizada as operações de seleção, cruzamento e mutação.No método selecaoTorneio() acontece a operação seleção e neste trabalho o tipo escolhido foi o de torneio, neste caso, são escolhidos três indivíduos da população aleatoriamente e é selecionado o que tiver o menor valor de aptidão. No método crossover() acontece a operação de cruzamento e para realização deste trabalho o tipo de crossover utilizado foi o n-pontos. A taxa de cruzamento neste trabalho foi de 60% (0.6) e a taxa de mutação foi de 3% (0.03). Vale ressaltar que o cruzamento no programa é realizado de forma a garantir que os indivíduos resultantes embora diferentes sempre sejam válidos, ou seja, obedeçam às restrições de demanda. No pacote busca_aleatoria, busca_aleatoria, a classe Buscaalet faz processo da busca aleatória. Nesta classe é estabelecido um mínimo como critério de parada e toma-se como base o mesmo formato de dados utilizado em indivíduo do Algoritmo Genético para compor valores, um vetor de 9 posições representado as variáveis. Nesta classe, para formação dos valores também são usadas as restrições de demanda.
DADOS ESTATÍSTICOS Foi calculado o tempo de 30 execuções. Esses dados servirão servir ão para calcular a média, o desvio e o teste t. Nesta parte do trabalho foi utilizada a linguagem R para calcular os parâmetros estatísticos.
O vetor “a” no programa acima representa os tempos de execução em milissegundos da busca aleatória aleatória e o vetor “b” representa os tempos do algoritmo genético. A média, a variância e o desvio padrão pode ser visualizado através dos comando mean(), var() e sd(). Por fim o teste t pode ser visto através do comando t.teste(a, b, var.equal=FALSE). O critério FALSE é adotado devido as variâncias serem diferentes.