1. O Problema do
Transporte Aplicado a
Grafos
Eduardo Oliveira de Souza
Gabryella Bloss Romero
Tatyana Bitencourt Soares de Oliveira
Projeto de Graduação
Orientação: Prof. Dr. Marcelo Henriques de Carvalho
Área de Concentração: Programação Linear
Monografia apresentada como requisito da qualificação para a obtenção do tı́tulo de
bacharel em Ciência da Computação.
dct ufms
Departamento de Computação e Estatı́stica
Centro de Ciências Exatas e Tecnologia
Universidade Federal de Mato Grosso do Sul
9 de dezembro de 2005
2. Resumo
Este trabalho aborda o problema do transporte sob uma nova visão: usando a teoria
dos grafos. Aqui é proposto um algoritmo baseado no simplex, metodo da programação
linear para otimização de esquemas de transporte e de atribuição. Um exemplo tambem é
desenvolvido para melhor entendimento do algoritmo proposto. Por fim, há uma descrição
comportamental da aplicação Web desenvolvida em linguagem Java, no qual foi aplicado
o algoritmo proposto. Para a implementação, foi aplicado um caso de uso no qual é
otimizada a distribuição dos professores entre as matérias de acordo com a afinidade do
professor com cada disciplina.
2
4. Capı́tulo 1
Introdução
O algoritmo apresentado nesse trabalho resolve um problema denominado proble-
ma do transporte, também conhecido na literatura como Hitchcock problem. Trata-se,
basicamente, da minimização de custos de transporte, podendo ser modelado até para
resolver um problema de atribuição. Para melhor compreensão do algoritmo é necessária
uma descrição mais formal do problema:
São dados m centros produtores com as quantidades a1...am representando as capaci-
dades de produção e n distribuidores que requerem as quantidades b1...bn, respectivamente.
O custo para transportar uma unidade do centro de produção i para o distribuidor j é
cij ≥ 0. O problema trata-se de determinar a quantidade i de xij produtos que cada cen-
tro produtor i vai enviar ao distribuidor j de maneira que a demanda seja completamente
atendida e que o custo total dos transportes seja mı́nimo. Isso quer dizer que o objetivo
é obter o resultado da seguinte expressão:
min
m
X
i=1
n
X
j=1
cijxij
É importante fazermos algumas observações sobre restrições aos dados recebidos pelo
algoritmo, tais como:
•
m
X
i=1
ai ≥
n
X
j=1
bj;
•
m
X
i=1
xij ≤ ai i = 1, 2, ..., m;
•
m
X
i=1
xij ≥ bj i = 1, 2, ..., n.
4
5. dct-ufms
Existem aspectos nas restrições acima que deve ser considerados. Tratam-se das
desigualdades. Como sabemos, o problema para o qual buscamos uma solução é de
otimização. Sendo assim, no caso da primeira restrição, a desigualdade que define que
a produção deve ser maior ou igual à soma das quantidades requisitadas pelos centros
distribuidores pode ser substituı́da por uma igualdade. Como não há necessidade de que
a produção seja maior que o consumo, também não há motivo para que se gaste com o
transporte desses produtos. O mesmo vale para as outras duas restrições. Não há motivo
para que a quantidade de produtos produzida seja maior que a quantidade transportada,
basta ser igual. Da mesma maneira que não há porque a quantidade de produto trans-
portado ser maior que a demanda, tendo em vista que isto acarretaria em um custo de
transporte desnecessário. Levando em conta essas considerações, podemos reescrever as
nossas restrições da seguinte maneira:
•
m
X
i=1
ai =
n
X
j=1
bj;
•
m
X
i=1
xij = ai i = 1, 2, ..., m;
•
m
X
i=1
xij = bj i = 1, 2, ..., n.
A abordagem apresentada aqui para o problema do transporte é incomum, uma vez
que trata-se de um problema inerente aos tópicos de programação linear, vertente da
matemática que resolve problemas de otimização,como o problema do transporte, com
a utilização de um algoritmo especı́fico denominado simplex. A solução proposta aqui
utiliza grafos, aplicando a solução matemática usada na programação linear de maneira
mais dinâmica e de fácil compreensão.
5
6. Capı́tulo 2
O Problema do Transporte e Grafos
Primeiramente, vamos definir a estrutura de um grafo para o nosso problema. Seja
um grafo G=(V,E) bipartido completo, onde a partição A representa os produtores e a
partição B representa os consumidores. Observe a Figura 2.1
Cada produtor e cada distribuidor possuem uma capacidade, de produção e de con-
sumo, respectivamente. As arestas, ao longo do algoritmo, possuem pesos variados, que
representam a quantidade de produto transportado pela aresta xij do produtor i ao dis-
tribuidor j. A solução é formada pelas arestas com pesos não-nulos.
A primeira solução sugerida foi aplicar o algoritmo de fluxo em grafos. O grafo repre-
sentando o problema do transporte seria adaptado para a aplicação do algoritmo inserindo
um vértice de origem, o qual estaria ligado com todos os produtores por arestas dirigidas.
Outra adaptação seria a inserção de um vértice destino, no qual incidiriam várias arestas,
uma aresta vinda de cada um dos distribuidores. A adaptação pode ser visualizada na
Figura 2.2.
As arestas seriam todas dirigidas, com origem nos produtores e incidência nos dis-
tribuidores. Essa solução tornou-se desinteressante, tendo em vista as inúmeras adap-
tações realizadas, as quais modificam o grafo totalmente. Em termos de processamento,
essas adaptações poderiam custar muito tempo. Por esses motivos a idéia de adaptação foi
deixada de lado, em detrimento de uma solução que não necessitasse de adaptações. Esta
é a solução que trataremos aqui, inspirada no simplex, como já foi citado anteriormente.
Fig. 2.1: Exemplo de grafo aplicado ao problema do transporte.
6
7. 2.1. Um Exemplo dct-ufms
Fig. 2.2: Grafo da Fig.2.1 adaptado para fluxo em redes.
2.1 Um Exemplo
Para demonstrarmos o problema e sua solução de maneira mais clara, observe o seguinte
exemplo:
Seja o seguinte esquema de distribuição entre produtores e distribuidores. Os números
à esquerda e à direita dos pontos significam a capacidade de produção e a demanda,
respectivamente.
Trata-se de uma solução qualquer, que pode ser melhorada, remanejando o transporte
de mercadorias. Por exemplo, adicionando um fluxo de mercadorias entre o produtor 1 e
o distribuidor 2 e adaptando o resto do esquema de acordo com as restrições apresentadas
anteriormente, temos uma diminuição no custo total do transporte.
7
8. Capı́tulo 3
O Algoritmo
O algoritmo para determinar o esquema de transporte de custo mı́nimo encontra,
primeiramente, uma solução inicial. Esta solução inicial dificilmente será a melhor, uma
vez que ela é gerada pelo algoritmo sem a menor preocupação com os custos. Basta apenas
que a solução atenda às restrições que apresentamos anteriormente. O trabalho principal
do algoritmo é gerar, a cada iteração, versões melhoradas do esquema de transporte a
partir da solução inicial, através de trocas dos valores dos transportes realizados entre os
centros produtores e consumidores. O esquema de transporte de menor custo terá sido
encontrado quando não houver maneira de melhorar, ou seja, de diminuir, o custo do
esquema encontrado na iteração anterior.
1. Algoritmo min transp
2. Inicio
3. Encontre uma solução básica inicial
4. repita:
5. para todo i ∈ produtores faça
6. para todo j ∈ distribuidores faça
7. se xij 6= 0 então
8. se xij diminui o custo entao
9. xij = min valor ciclo(xij)
10. atualizar solucao()
11. ate não existir xij que melhore a solução
12. fim
Alguns aspectos do algoritmo precisam ser esclarecidos. Na linha 1 temos uma
solução básica inicial. Como sabemos, nosso algoritmo é de otimização, ou seja, um mel-
horamento contı́nuo de soluções válidas parciais em busca da melhor solução, sinalizada
por algum critério de parada. Uma solução básica inicial é uma solução válida, na qual as
restrições apresentadas são respeitadas. Trata-se do ponto de partida em busca de uma
solução ótima. Para diminuir o custo de uma solução válida parcial, são verificadas todas
as arestas não pertencentes à solução. Esta verificação é realizada da seguinte maneira:
a aresta em teste xij é inserida na solução básica. Se o custo de transporte da aresta xij
8
9. dct-ufms
é menor que o custo já existente na solução parcial, a aresta é inserida na solução par-
cial, gerando uma nova, de custo menor em relação à anterior. As funções apresentadas,
min valor ciclo(xi) e atualizar solucao( ) foram inseridas para a compreensão mais clara
do algoritmo. Ao inserirmos uma aresta em um grafo bipartido, como o usado para esta
solução do problema do transporte, um ciclo é formado. A função min valor ciclo(xij) en-
contra o valor mı́nimo nos transportes pertencentes ao ciclo gerado pela inserção da aresta
xij na solução. Este valor retornado é o menor valor entre um conjunto de arestas não
adjacentes, ou seja, alternadas, no ciclo em questão. Este conjunto é obtido da seguinte
maneira: a partir do vértice i, pertencente ao conjunto dos produtores, da aresta xij in-
serida, percorremos o menor caminho no grafo até o vértice j, pertencente ao conjunto
dos consumidores, numerando as arestas por ordem de visitação. O conjunto de arestas
a ser considerado para definir a quantidade de produto transportado pela nova aresta xij
são as arestas de numeração par.
Poderı́amos abstrair esse conjunto de outra maneira: considere o grafo como sendo
um grafo dirigido G = (V,E), onde todas as arestas partem dos produtores e incidem nos
consumidores. Percorrendo o menor caminho entre os vértices i e j de xij, considere
as arestas que estão na direção contrária ao caminho percorrido a partir de i. Após a
decisão pela inserção da aresta xij na solução, a função atualizar solucao() remove uma
das arestas do ciclo gerado pela inserção de xij da solução parcial.
Em alguns casos a inserção de uma aresta no grafo bipartido não necessariamente
gera um ciclo. Isso acontece quando o grafo é desconexo. Para resolvermos esse problema,
basta acrescentar uma aresta que transporte um valor nulo à solução inicial, de maneira
que o grafo fique conexo. Dessa maneira, não será necessário alterar todo o algoritmo,
apenas sua inicialização.
9
13. Capı́tulo 5
A Implementação
5.1 Descrição da Implementação
O algoritmo proposto neste projeto foi implementado na linguagem Java[1] e pode
ser descrito em dois passos: determinar a solução inicial e melhorar a solução enquanto
possı́vel.
1)Determinar a solução inicial.
O primeiro passo é realizado atribuindo-se uma solução arbitrária ao problema, ex-
istindo três possibilidades:
• a[i] < b[j] : indica que o produtor pode atender a demanda do consumidor e toda
a capacidade de produção de a[i] é enviada a b[j];
• a[i] > b[j]: indica que o consumidor terá toda sua demanda atendida pelo produtor
i;
• a[i] = b[j]: indica que o produtor atende completamente a demanda do consumidor.
Neste caso, o grafo formado pelas arestas que pertencem à solução ficaria desconexo.
Assim, ao buscar por arestas que melhorem a solução, haveria o caso em que a aresta
escolhida simplesmente conectaria as componentes do grafo, sem formação de um
ciclo. Quando a[i] = b[j], incluimos uma aresta fictı́cia com fluxo zero na solução
garantindo que o grafo continue sempre conexo (pois a cada iteração, no processo de
otimização da solução, uma aresta é retirada e outra é acrescentada),sem alterações
na solução.
13
14. 5.1. Descrição da Implementação dct-ufms
O primeiro passo é descrito de acordo com o algoritmo a seguir:
i = 1;
j = 1;
enquanto (i ≤ m)e(j ≤ n)faça
se a[i] < b[j] então
x[i][j] = a[i];
i++;
b[j] = b[j] − a[i];
se b[j]=0 então
j++;
senão
x[i][j] = b[j];
j++;
a[i] = a[i] - b[j];
fimenquanto
2)Melhorar a solução enquanto possı́vel.
Para melhorar a solução inicial, busca-se na matriz de fluxo uma aresta (i, j) que não
faz parte da solução inicial.
O próximo passo é buscar um ciclo no grafo, que é feito buscando por um caminho que
parta de i e chegue em j. Poderia ter sido feita uma busca em profundidade ou largura,
mas haverá apenas um caminho de um vértice a outro, sendo mais fácil encontrar caminho
mı́nimo, supondo que não existam ciclos. Assim, os vértices fonte e destino são os vértices
que ligam a aresta candidata a entrar na solução e que melhore a mesma. Encontrando
o caminho entre os vértices que ligam a aresta candidata, e adicionando a mesma a esse
caminho, temos o ciclo. Deve-se verificar, agora, se a inclusão da aresta diminui o custo
da solução anterior. Então o que fazemos em seguida é percorrer essa coleção e verificar
os custos das arestas. Se utilizássemos uma busca em largura ou em profundidade, o que
terı́amos como resposta seria apenas a existência ou não de ciclo, e precisarı́amos de uma
consulta à matriz para descobrir qual o ciclo nesta etapa. A última tarefa consiste apenas
em verificar se a inclusão da aresta melhora o custo da solução. Caso melhore, a aresta
(i, j) substitui a aresta de menor fluxo da solução.
14
15. 5.2. Estudo de Caso dct-ufms
O segundo passo é descrito de acordo com o algoritmo a seguir:
para i = 1 até m faça
para j = 1 até n faça
/ / procura por uma aresta que não faça parte da solução atual
se x[i][j] = 0 então
path = buscar caminho...
/ /na verdade busca um ciclo no grafo que use a aresta [i][j]
se (path melhor que o caminho atual) então
cam atual = path
fimse
fimse
fimpara
fimpara
5.2 Estudo de Caso
Um caso particular do problema do transporte é o problema de distribuição entre
professores e disciplinas e foi utilizado como estudo de caso, bem com para validar a
implementação realizada.
Este problema ser descrito como o do transporte, onde os professores são os produtores
e as disciplinas, os distribuidores. Uma particularidade desse problema é que a capacidade
da disciplina é sempre igual a 1 e a soma das capacidades dos professores deve ser igual à
quantidade total de disciplinas. O custo de cada aresta indica a preferência do professor
em ministrar a disciplina, variando entre 0 e 10. O objetivo do problema é que o maior
número de professores possam ministrar as disciplinas de maior preferência.
O estudo de caso foi realizado com base nos dados do Departamento de Computação
e Estatı́stica da UFMS. Os dados foram obtidos através da implementação de um sistema
Web, escrito na linguagem Java[1], onde cada professor poderia indicar sua preferência
pelas matérias disponı́veis no DCT.
Exemplo de grafo aplicado ao problema da distribuição do professores entre as disci-
plinas:
15
16. 5.2. Estudo de Caso dct-ufms
Uma adaptação para a aplicação se fez necessária: as notas dadas pelos professores à
cada matéria são números inteiros entre 0 e 10, onde 0 é a menor preferência e 10 a maior
preferência. Devemos lembrar que o algoritmo proposto para resolução do problema do
transporte encontra a solução de custo mı́nimo. Para tal, solução encontrada foi inverter
as notas. Por exemplo, caso a nota do professor fosse 10, a nota seria modificada para 1
(e não para zero, pois existe o caso das arestas fictı́cias). Se a nota fosse 8, a nota seria
modificada para 3.
Após os dados coletados, foi utilizada a implementação do algoritmo do capı́tulo 3,
para descobrir a distribuição ótima.
16
17. Referências Bibliográficas
[1] Java Technology. http://java.sun.com, 2005.
[2] T. Cormen,C. Leiserson,R. Rivest. Introduction to Algorithms, 2001.
[3] A. DulmageN. Mendelsohn. The ACM Digital Library Matrices Associated With the
Hitchcock Problem. ,409–418, 1962. http://doi.acm.org/10.1145/321138.321139.
[4] R. Totschek, R. Wood. Vertex cover: An Investigation of RealTime Solu-
tion of the Transportation Problem. Journal of the ACM , 230–239, 1961.
http://doi.acm.org/10.1145/321062.321070 .
[5] P. Bregalda, C. Bornstein. Introdução a Programação Linear. Editora Campus, 1981.
[6] F. Glover, D. Karney, e D. Klingman. A note on computational studies for solving
transportation problems. The ACM Digital Library, 7–11, 1973.
[7] J. Orlin. A polynomial time primal network simplex algorithm for minimum cost
flows. The ACM Digital Library, 474–481, 1996.
[8] Teoria dos Grafos. Wikipedia, 2005. http://pt.wikipedia.org/wiki/Teoria dos Grafos
[9] M. Goldbarg, H. Pacca Combinatória e Programação Linear: Modelos e Algoritmos.
Editora Campus, 2000.
17