faculdade norte capixaba de sâo mateus análise e desenvolvimento

Transcrição

faculdade norte capixaba de sâo mateus análise e desenvolvimento
0
FACULDADE NORTE CAPIXABA DE SÂO MATEUS
ANÁLISE E DESENVOLVIMENTO DE SISTEMAS
ELTON DOUGLAS SILVA
A OTIMIZAÇÃO DE PROBLEMAS DE CAMINHO MAIS CURTO ENTRE DOIS
PONTOS EM UMA ROTA, UTILIZANDO ALGORITMOS BASEADOS EM
GRAFOS.
SÃO MATEUS
2012
1
ELTON DOUGLAS SILVA
A OTIMIZAÇÃO DE PROBLEMAS DE CAMINHO MAIS CURTO ENTRE DOIS
PONTOS EM UMA ROTA, UTILIZANDO ALGORITMOS BASEADOS EM
GRAFOS.
Trabalho de Conclusão de Curso apresentado ao
programa de Graduação no Curso Superior
Tecnológico em Analise e Desenvolvimento de
Sistemas da Faculdade Norte Capixaba de São
Mateus, como requisito para obtenção do grau de
Tecnólogo em Analise e Desenvolvimento de
Sistemas.
Orientador: Lucas Costa Jardim.
SÃO MATEUS
2012
2
Catalogação na fonte elaborada pela “Biblioteca Dom Aldo Gerna”/UNISAM
S586o
Silva, Elton Douglas
A otimização de problemas de caminho mais curto entre dois pontos em uma rota,
utilizando algoritmos baseados em grafos/– São Mateus: UNISAM /Faculdade Norte
Capixaba de São Mateus, 2012.
58.f : enc.
Orientador: Lucas Costa Jardim
Trabalho de conclusão de curso (Tecnólogo em Análise e Desenvolvimento de
Sistemas)
UNISAM / Faculdade Norte Capixaba de São Mateus, 2012.
1.Análise 2. Protótipo 3. Dijkstra I. Silva, Elton Douglas II.UNISAM /
Faculdade Norte Capixaba de São Mateus, 2012. III. Título.
CDD 005.1
3
ELTON DOUGLAS SILVA
A OTIMIZAÇÃO DE PROBLEMAS DE CAMINHO MAIS CURTO ENTRE DOIS
PONTOS EM UMA ROTA, UTILIZANDO ALGORITMOS BASEADOS EM
GRAFOS.
Trabalho de Conclusão de Curso apresentado ao programa de Graduação no Curso Superior
Tecnológico em Analise e Desenvolvimento de Sistemas da Faculdade Norte Capixaba de São
Mateus, como requisito para obtenção do grau de Tecnólogo em Analise e Desenvolvimento de
Sistemas.
Aprovada em 24 de novembro de 2012
COMISSÃO EXAMINADORA
_____________________________________________________
Profº Lucas Costa Jardim
Faculdade Norte Capixaba de São Mateus
Orientador
_____________________________________________________
Profº Ramilton Costa Júnior
Faculdade Norte Capixaba de São Mateus
Membro 1
_____________________________________________________
Profº Temístocles A. Rocha
Faculdade Norte Capixaba de São Mateus
Membro 2
4
Dedico este trabalho a Deus, meu
Senhor, por ter me dado forças para
completar este desafio, esta etapa da
minha vida acadêmica, por me amparar
nos momentos de angustia e fraqueza,
pois sei que sem Ele eu não teria
conseguido. Que toda honra e glória seja
dada a Ti Senhor.
Dedico aos meus familiares por sempre
me apoiarem e estarem presentes
incentivando.
5
Meus sinceros agradecimentos ao
Professor (orientador) Lucas Costa
Jardim, por ter aceitado este desafio
comigo, por ter me ajudado nesta batalha
e por ter contribuindo para a conclusão
deste projeto. Professor Lucas, muito
obrigado.
Meus sinceros agradecimentos a Ivani
Francisca dos Santos, por sua imensa
ajuda, tanto intelectual quanto pessoal.
Por sempre está disposta a ajudar sem
cobrar nada em troca, pelos sinceros
gestos de tolerância, compreensão e
carinho. Ivani, muito obrigado.
Meus sinceros agradecimentos a todos os
professores que fizeram parte da minha
jornada acadêmica na instituição, sem
vocês esta jornada não poderia ter sido
completada. Professores, muito obrigado.
6
“A arte de programar consiste em
organizar e dominar a complexidade”.
(Edsger Dijkstra)
7
RESUMO
O presente trabalho tem como objetivo apresentar alguns aspectos sobre a Teoria
Geral dos Grafos, pseudocódigos que trabalham com grafos buscando a otimização
(melhor resposta) para encontrar o menor caminho entre dois pontos em uma rota.
Para o levantamento das informações contidas nesta pesquisa, utilizou-se o
emprego de uma pesquisa exploratória, respaldando-se em pesquisas bibliográficas
e virtuais. Para uma melhor visualização, foi desenvolvido um Protótipo, no qual foi
aplicado o algoritmo selecionado como o mais indicado para solucionar o problema
proposto nesta pesquisa. A escolha do algoritmo se deu através de comparações
dos seus valores de complexidade, análise assintótica.
PALAVRAS-CHAVE: Análise. Protótipo. Dijkstra.
8
ABSTRACT
This work aims to present some aspects about the General Theory of Graphs,
pseudocódigos working with graphs seeking optimization (best response) to find the
shortest path between two points on a route. To survey the information contained in
this research, we used the employment of an exploratory research, supporting
research into bibliographic and virtual. For best viewing, we developed a prototype, in
which we applied the algorithm selected as the most suitable for solving the problem
proposed in this research. The choice of algorithm is made by comparing the values
of complexity, asymptotic analysis.
KEYWORDS: Analysis. Prototype. Dijkstra.
9
LISTA DE FIGURAS
FIGURA 1.0 – PROBLEMA DADO A EULER EM 1736............................................21
FIGURA 2.0 - GRAFO MONTADO DO PROBLEMA DADO A EULER EM 1736....22
FIGURA 3.0 – GRAFO..............................................................................................22
FIGURA 4.0 – GRAFO DIRECIONADO....................................................................24
FIGURA 5.0 – GRAFO NÃO DIRECEIONADO.................................................... ......24
FIGURA 6.0 – GRAFO PONDERADO......................................................................25
FIGURA 7.0 – GRAFO SIMPLES.............................................................................25
FIGURA 8.0 – GRAFO COMPLETO........................................................................25
FIGURA 9.0 – ALGORTIMOS EM DIAGRAMA DE BLOCOS ................................26
FIGURA 10.0 - ALGORITMO TEXTUAL..................................................................26
FIGURA 11.0 – PSEUDOCÓDIGO DO ALGORITMO DE WARSHALL...................27
FIGURA
12.0
–
PSEUDOCÓDIGO
DO
ALGORITMO
DE
DIJKSTRA
–
RELAXAMENTO DAS ARESTAS.............................................................................30
FIGURA 13.0 – GRAFO ORIENTADO.....................................................................31
FIGURA 14.0 – PSEUDOCÓDIGO ALGORITMO DE BELLMAN-FORD.................32
FIGURA 15.0 – ANÁLISE ASSINTÓTICA – ............................................................38
FIGURA 16.0 – DIAGRAMA DE CASO DE USO – PROTÓTIPO............................44
FIGURA 17.0 – DIAGRAMA DE ATIVIDADES – EXECUTAR DIJKSTRA...............46
FIGURA 18.0 – DIAGRAMA DE SEQUÊNCIA.........................................................47
FIGURA 19.0 – DIAGRAMA DE CLASSE................................................................48
FIGURA 20.0 – GRAFO PRÉ-DISPOSTO DO PROTÓTIPO..................................49
FIGURA 21.0 – PROTÓTIPO – TELA PRINCIPAL..................................................50
FIGURA 21.1 – PROTÓTIPO – TELA PRINCIPAL – PARTE INFERIOR ..............50
FIGURA
21.2
–
PROTÓTIPO
–
SIMULAÇÃO
ENTRADA
DE
DADOS
MANUALMENTE......................................................................................................51
10
LISTA DE TABELAS
TABELA 1.0 – SEQUÊNCIA DE DIAGRAMAS – ALGORITMO DE DIJKSTRA........28
TABELA 2.0 – TABELA COM OS DADOS DO GRAFO DA FIGURA 13.0 ..............31
TABELA 3.0 –EXEMPLO PL.....................................................................................39
TABELA 4.0 – COMPLEXIDADE DOS ALGORITMOS.............................................41
11
SUMÁRIO
1 INTRODUÇÃO .................................................................................................. 13
1.1 JUSTIFICATIVA DO TEMA.................................................................................. 13
1.2 DELIMITAÇÃO DO TEMA ................................................................................... 14
1.4 OBJETIVOS ........................................................................................................ 15
1.4.1 OBJETIVO GERAL ................................................................................................ 15
1.4.2 OBJETIVOS ESPECÍFICOS ..................................................................................... 15
1.5 HIPÓTESE .......................................................................................................... 15
1.6 META................................................................................................................... 15
1.7 METODOLOGIA .................................................................................................. 16
1.7.1 CLASSIFICAÇÃO DA PESQUISA ............................................................................. 16
1.7.2 TÉCNICAS PARA COLETA DE DADOS ...................................................................... 17
1.7.3 FONTES PARA COLETA DE DADOS ......................................................................... 17
1.7.4 CARACTERIZAÇÃO DA AMOSTRA PESQUISADA ....................................................... 18
1.7.5 INSTRUMENTO PARA A COLETA DE DADOS ............................................................. 18
1.7.6 POSSIBILIDADE DE TRATAMENTO E ANÁLISE DOS DADOS. ....................................... 18
1.8 APRESENTAÇÃO DOS CONTEÚDOS DAS PARTES DO TRABALHO............ 19
2.0 REFERENCIAL TEÓRICO ......................................................................... 20
2.1 MODELAGEM DE PROBLEMAS .................................................................... 2020
2.2 TEORIA GERAL DOS GRAFOS .......................................................................... 21
2.2.1 TIPOS DE GRAFOS ............................................................................................... 23
2.3 ALGORITMOS..................................................................................................... 26
2.3.1 ALGORITMOS DE MENOR CAMINHO OU CAMINHO MÍNIMO ......................................... 27
2.3.3 ALGORITMO DE BELLMAN-FORD ........................................................................... 31
2.4 ANÁLISE DE ALGORITMOS ............................................................................... 34
2.4.1 COMPLEXIDADE DOS ALGORITMOS - ANÁLISE ASSINTÓTICA .................................... 35
2.4.2 PROGRAMAÇÃO LINEAR.......................................................................................39
2.4.3 ALGORITMO ESCOLHIDO ...................................................................................... 41
2.5 FERRAMENTAS (IDE’S) E LINGUAGEM UTILIZADAS NO DESENVOLVIMENTO
DO SOFTWARE ........................................................................................................ 42
12
2.5.1 C# ..................................................................................................................... 42
2.5.2 UML - UNIFIED MODELING LANGUAGE OU LINGUAGEM DE MODELAGEM DE DADOS .... 42
3.0 IMPLEMENTAÇÃO DIJKSTRA – PROTÓTIPO ................................... 44
3.1 DIAGRAMA DE CASO DE USO .......................................................................... 44
3.1.2 DIAGRAMA DE ATIVIDADES ................................................................................... 45
3.1.3 DIAGRAMA DE SEQUÊNCIA ................................................................................. 466
3.1.4 DIAGRAMA DE CLASSES..................................................................................... 477
3.2 GRAFO DE ESTUDOS – PROTÓTIPO ............................................................. 488
3.3 PROTÓTIPO ..................................................................................................... 499
3.3.1 IMPLEMENTAÇÃO DO ALGORITMO DE DIJKSTRA EM C SHARP ............................... 522
4.0 CONCLUSÃO E RECOMENDAÇÕES .................................................. 555
4.1 CONCLUSÃO .................................................................................................... 555
4.2 RECOMENDAÇÕES ......................................................................................... 555
5.0 REFERÊNCIAS BIBLIOGRÁFICAS ...................................................... 577
13
1 INTRODUÇÃO
Gastos e tentativa de otimização, são fatores comuns no cotidiano de pessoas
físicas e jurídicas. Quem nunca se perdeu ou gastou mais combustível errando o
caminho para a casa de um “primo” que morava em outra cidade? Qual empresa
que nunca mudou uma rota dos seus veículos tentando achar o caminho mais curto
ou mais econômico para atingir ou concluir determinada meta? Bem, hoje com as
novas tecnologias (como o GPS) estes tipos de problemas se tornaram mais fáceis
de contornar.
Este trabalho abordará algoritmos que trabalham na otimização desses problemas
(menor caminho, melhor rota), os quais (os problemas) podem ser montados
graficamente utilizando grafos.
Padrões algorítmicos que foram criados para fins parecidos também foram
abordados, assim como a teoria dos grafos (onde foram apresentados apenas os
conceitos básicos, acreditando-se dar um bom suporte para o acompanhamento da
pesquisa).
Na etapa final foi desenvolvido um software (protótipo) no qual está implementado o
algoritmo que se foi identificado como o mais indicado para otimização deste tipo de
problema (menor caminho entre dois pontos de uma rota), onde o mesmo pode ser
alimentado diretamente pelo usuário.
1.1 JUSTIFICATIVA DO TEMA
Solução e otimização de problemas, são resultados constantemente buscados pela
humanidade. Trabalhos, pesquisas e abundantes denotações científicas foram e são
criadas para tais feitos. Uma das formas encontradas e utilizadas para obtenção da
otimização e solução de famosos problemas dados à sociedade (pontes de
Königsberg em 1736, o problema das 4-Cores de Francis Guthris/De Morgan em
1852), foi o uso da Teoria dos Grafos.
14
A Teoria dos Grafos é vista como uma das mais importantes áreas da matemática
discreta, a mesma é utilizada na construção de modelos para a visualização dos
problemas de um ângulo proporcionalmente melhor.
Com o avanço tecnológico depois da criação do primeiro computador eletrônico
(Eniac – 1946), o desenvolvimento e estudo dos algoritmos foram impulsionados.
Segundo Oliveira e Nunes (2011), nos anos 70 e 80 ocorrendo o desenvolvimento
da base matemática da Teoria dos Grafos, a mesma passou a ser utilizada com a
informática, na época na área de Análise de Redes Sociais.
Como fora demonstrado, a Teoria dos Grafos, ajudou e poderá ajudar a modelar
problemas de diversos setores de “N” áreas, que poderão abranger desde
problemas pequenos como serviços de entrega de pizzas ou problemas maiores
como atendimento bancário de aposentados, menor caminho entre dois pontos de
uma rota, dentre outros. Uma vez modelado o problema em questão, se pode utilizar
de algoritmos para ajudar na otimização do mesmo.
1.2 DELIMITAÇÃO DO TEMA
O presente trabalho, através de pesquisas (bibliográficas e virtuais), visa obter
informações e abordar métodos (algoritmos) que foram desenvolvidos com o
objetivo de trazer respostas mais computacionais (rápidas e mais precisas) para
otimização de problemas de caminho mais curto entre dois pontos de uma rota.
1.3 FORMULAÇÃO DO PROBLEMA
Baseando-se na diminuição de gastos e tempo, ao se otimizar qualquer processo de
um determinado trabalho, estamos gerando lucro e ou diminuição de custos.
Qual o algoritmo que melhor se enquadra para se obter de forma otimizada, o menor
caminho entre dois pontos de uma rota?
15
1.4 OBJETIVOS
1.4.1 OBJETIVO GERAL
Apresentar a utilização de algoritmos baseados em grafos na otimização de
problemas de menor caminho em uma rota, através um software (protótipo) que foi
desenvolvido, podendo o mesmo ser alimentado diretamente pelo usuário.
1.4.2 OBJETIVOS ESPECÍFICOS
 Pesquisar sobre algoritmos que tratam de problemas de menor
caminho.
 Levantar informações sobre a Teoria dos Grafos.
 Identificar qual o melhor algoritmo para se trabalhar com problemas de
menor caminho, onde o mesmo só utilize pesos de valores positivos.
 Desenvolver um software (protótipo) onde será aplicado um algoritmo
que melhor se enquadre no problema posposto nesta pesquisa e que
tenha a menor taxa de complexidade (valor assintótico), o qual irá
identificar o menor caminho entre dois pontos em uma rota.
1.5 HIPÓTESE
Acredita-se que ao final desta pesquisa, será possível enxergar a praticidade e
agilidade que se ganha ao implementarmos algoritmos baseados em grafos em
softwares que indicam o menor caminho entre dois pontos de uma rota.
1.6 META
Expor como a aplicabilidade de algoritmos baseados em grafos pode ajudar na
otimização de problemas de menor caminho em uma rota.
16
1.7 METODOLOGIA
Para Viegas (apud Reis, 2008, p. 44), “a metodologia é o conjunto de técnicas e
processos utilizado pela ciência para formular e resolver problemas de aquisição
objetiva do conhecimento de maneira sistemática.”.
Na metodologia, utiliza-se de técnicas propostas para obtenção de êxito do
problema proposto na pesquisa elaborada. Trabalhando com a mineração dos dados
pesquisados e fornecidos, mostrando as formas com que os mesmos foram
modelados.
1.7.1 CLASSIFICAÇÃO DA PESQUISA
Para Gil (2007), é possível classificar as pesquisas em três grandes grupos:
exploratórios, descritivas e explicativas. Onde as pesquisas exploratórias envolvem
levantamento bibliográfico, entrevistas com pessoas que tiveram experiências
práticas com o problema pesquisado e ou análise de exemplos. Já as pesquisas
descritivas têm o objetivo primordial à descrição das características dos fatores
estudados e estabelecendo as relações entre variáveis. Nas pesquisas explicativas
a preocupação central seria identificar os fatores que determinam ou que contribuem
para a ocorrência dos fenômenos, portanto, é neste tipo de pesquisa onde há um
maior aprofundamento da realidade, pois a mesma explica o porquê das coisas.
Reis (2008, p.51), dentro das pesquisas exploratórias, descreve bem o conceito da
pesquisa bibliográfica:
A pesquisa bibliográfica é a mais simples técnica de pesquisa. Ela explica
um problema, fundamentando-se apenas nas contribuições secundárias, ou
seja, nas informações e dados extraídos de livros de leitura corrente e de
referencias, de revistas impressas e virtuais, material audiovisual,
entrevistas, documentos, etc. de diferentes autores que versam sobre o
tema selecionado para o estudo.
Foi utilizada para a conclusão do projeto a pesquisa exploratória, respaldando-se
nos levantamentos de dados e análise de exemplos que serão obtidos através de
17
pesquisas bibliográficas e virtuais, visto que, não foram abordados problemas de
empresas ou setores reais, mas sim, exemplos para a compreensão do trabalho
proposto.
1.7.2 TÉCNICAS PARA COLETA DE DADOS
Richardson (1999, p. 219) “as técnicas de pesquisa não podem ser utilizadas como
receitas de instrumentos neutros, mas como meios de obtenção de informação cujas
qualidades e limitações devem ser controladas”.
Qualquer técnica utilizada para coleta de dados em um referido problema, pesquisa
e ou trabalho, não pode se utilizar de meios estagnados, parados, é preciso
observar o que se procura encontrar e quais os meios que estão sendo utilizados
para determinado fim.
Foram utilizadas no referente trabalho, técnicas de coleta e levantamento de dados
em fontes bibliográficas e virtuais (sites, fóruns, artigos).
1.7.3 FONTES PARA COLETA DE DADOS
As fontes para coletas de dados podem ser dividir em dois tipos: os de fontes
primárias e fontes secundárias.
Segundo Andrade (2001), fontes primárias são formadas por obras ou textos
originais, conteúdos ainda não trabalhados, sobre determinado assunto. As fontes
primárias, pela sua relevância, dão origem a outras obras, que vão formar uma
literatura ampla sobre aquele determinado assunto.
Para Cervo e Bervian (apud MERTENS; FUMANGA; TOFFANO; SIQUEIRA, 2007,
p. 60) “as fontes secundárias são provenientes de material bibliográfico colhido em
livros, revistas periódicas, jornais, anais de congressos e demais fontes impressas
ou eletrônicas”.
18
Seguindo estas linhas de raciocínio, foram utilizadas fontes secundárias, pois o
mesmo trabalhou com pesquisas bibliográficas e virtuais, atribuindo a base do seu
conteúdo nas informações adquiridas com as pesquisas.
1.7.4 CARACTERIZAÇÃO DA AMOSTRA PESQUISADA
O trabalho foi realizado através de pesquisas bibliográficas (livros, fontes impressas,
etc.) e virtuais (sites, artigos, fóruns), esperando adquirir informações necessárias
para a conclusão do mesmo com êxito.
1.7.5 INSTRUMENTO PARA A COLETA DE DADOS
Utilizaram-se pesquisas bibliográficas e virtuais, assim como leituras de materiais
impressos que se correlacionavam com o tema e problema sugeridos nesta
pesquisa.
Não se fez necessário a utilização de questionário ou outros instrumentos
semelhantes para coleta de dados referentes à pesquisa proposta.
1.7.6 POSSIBILIDADE DE TRATAMENTO E ANÁLISE DOS DADOS
Para Vergara (2003, p. 59), ”Tratamento dos dados refere-se àquela seção na qual
se explicita para o leitor como se pretende tratar os dados a coletar [...].”.
Partindo dessa premissa e visando elaborar uma pesquisa integra e sem erros, todo
o conteúdo pesquisado foi analisado, buscando evitar dados não precisos e
redundância de informações.
19
1.8 APRESENTAÇÃO DOS CONTEÚDOS DAS PARTES DO TRABALHO
Para a demonstração do objeto de estudo desta pesquisa, a mesma foi dividida em
05 capítulos:
Onde no primeiro capítulo é feita a Introdução, Justificativa do Tema, Delimitação do
tema, Formulação do problema, Objetivos (geral e específicos) e a Hipótese.
No segundo capítulo é exposto o Referencial Teórico, o qual fundamentaliza esta
pesquisa.
O terceiro capítulo apresenta o Protótipo, o qual se torna a parte prática deste
projeto, onde foi inserido o algoritmo (dentre os abordados por esta pesquisa) que
melhor se enquadrou para a resolução do problema proposto.
As Conclusões referentes a esta pesquisa e Recomendações para continuação do
protótipo (possíveis melhorias), setores onde o mesmo poderia ser empregado, etc.,
encontram-se no capítulo 4.
No capítulo 5 estão todas as referências bibliográficas utilizadas para a conclusão
deste projeto.
20
2.0 REFERENCIAL TEÓRICO
2.1 MODELAGEM DE PROBLEMAS
Ao tentarmos obter uma visualização mais ampla e com representações mais
simplificadas de um determinado problema, a modelagem pode ser uma excelente
ferramenta a se utilizar.
Para Goldbarg e Luna (2005, p. 2) “Os modelos são representações simplificadas da
realidade que preservam, para determinadas situações e enfoques, uma
equivalência adequada.”.
Expondo-se um problema que antes se encontrara em forma contextual, para um
modelo visual (gráfico), fará com que se obtenha uma melhor amplitude do mesmo,
consequentemente, se atribuirá uma otimista capacidade para a simplificação do
mesmo.
É importante lembrar que, todo modelo deve passar por um processo de validação,
onde ocorrem verificações da sua representatividade, é verificado se o modelo
realmente está de acordo com a atividade para o qual foi elaborado.
O conceito que é aferido aos modelos, de que eles demonstram uma representação
substituta da realidade, implicam em um alcance limitado.
Goldbarg e Luna (2005) relata que para alcançarmos modelos eficientes, são
necessárias pelo menos três habilidades: Foco holístico, que seria indispensável
quando estamos procurando solucionar um problema e nossa solução pode criar
outros problemas que podem posteriormente anular nossos esforços; Tratamento
eclético da dimensão da análise, onde todos os métodos utilizados terão de ser os
mais livremente dispostos, e por último a Tradução adequada, onde se indica que,
para se ter um bom modelo, se exigirá ter uma boa tradução de todos os dados e
contexto do problema.
21
2.2 TEORIA GERAL DOS GRAFOS
A Teoria dos Grafos é vista como uma das mais importantes áreas da matemática
discreta e também na área da Ciência da Computação.
Alguns autores como Bonchev e Rouvray (1991), relatam que o primeiro registro
conhecido da teoria dos grafos foi feito pelo matemático suíço Leonhard Euler, que
viveu entre 1707 e 1783, o qual utilizou a mesma pela primeira vez em 1736 para
resolver um problema que lhe foi entregue pelos cidadãos da cidade prussiana de
Königsberg, a qual era cortada pelo rio Pregel, que abrange uma porção de terra
(ilha). O problema que lhe foi proposto era determinar se era passível começar um
passeio por qualquer ponto das margens do rio (Pregel), ou da ilha, e percorrer por
todas as pontes (eram 07 no total), cada uma somente uma única vez, e voltar ao
ponto de partida.
Figura 1.0 – Problema dado a Euler em 1736
Fonte: DEWDNEY. 20.000 léguas matemáticas, (2000).
Montando o problema em um grafo, em 1736, Euler mostrou que este passeio é
impossível, que o mesmo só seria possível, se em cada ponto (ilha) houvesse duas
pontes, uma para entrada e outra para saída, formando assim em cada ponto um
número par de pontes.
A figura 2.0 ilustra um possível esboço feito por Euler, montado o problema proposto
a ele em forma de grafo.
22
Figura 2.0 – Grafo montado do problema dado a Euler em 1736
Fonte: DEWDNEY, 20.000 léguas matemáticas, (2000).
Goodrich e Tamassia (2007) relatam de forma simples, porém direta, o conceito de
grafos, onde dizem que um grafo é uma forma gráfica de representar
relacionamentos que existem entre pares de objetos.
Um grafo de forma simples, nada mais é que a representação visual (gráfica) de
elementos que se interligam e que de certa forma tem uma interdependência entre
si. O mesmo pode ser amplamente utilizado para representação visual de
problemas, onde trará uma melhor visualização do mesmo.
Os elementos do grafo são denominados de vértices (nós), que é um conjunto não
vazio de objetos e estão interligados através de traços, denominados arestas, que
são um conjunto de pares não ordenados.
Para um melhor entendimento, podemos imaginar uma árvore (no conceito de
árvores binárias em algoritmo), vários elementos (vértices) que estão ligados entre si
graficamente através de traços (arestas).
A figura 3.0 ilustra um exemplo simples de grafo.
Figura 3.0 – Grafo
Fonte: Fonte: Adaptado pelo autor
23
No seu conceito matemático, um grafo é G(V, A), onde V são os vértices e A as
arestas, o conjunto V = {1, 2,..., v} será composto dos “n” nós do grafo, e A = {1, 2,...,
a} conterá as “n” arestas. Sendo que, dependendo da situação, as arestas podem
ser direcionadas ou não, e também podem trazer sobre si pesos (valores numéricos)
associados, tornando-os assim Grafos Ponderados.
Partindo do seu conceito matemático, temos então na figura 3.0, os seguintes dados
representando G(V, A):
V = {2,4,5,6,8};
A = { { 2, 4} { 2, 6} { 4, 2} { 4, 5} { 4, 6} { 5, 4} { 5, 6} { 6, 2} { 6, 4} { 6 ,5} {8, 4}};
Outro ponto importante na teoria dos grafos é entender como os vértices podem
estabelecer vínculos (ligações) através das arestas, definindo-se assim a vizinhança
de vértices.
Caso não haja valores associados às arestas, dizemos que o grafo é Rotulado. Não
se encontrando também orientação nas arestas, ou seja, direcionamento da direção
da mesma, e sendo um vértice ‘A’ “amigo” do vértice ‘B’ e vice-versa, os mesmos
possuem uma relação simétrica.
Goldbarg e Luna (2005, p. 489) dizem que “[...] dois vértices xi e xj são vizinhos ou
adjacentes quando existe uma aresta que liga xi a xj ou vice-versa.”.
É válido ressaltar que a noção de vizinhança se dá apenas a grafos não orientados.
2.2.1 TIPOS DE GRAFOS
Dentre os diversos tipos de grafos, existem os direcionados e não direcionados.
Para Goldbarg e Luna (2005, p. 485), “um grafo é dito direcionado quando o sentido
das ligações entre os vértices é importante. Nesse caso normalmente as arestas são
chamadas por arcos.”.
Para obtenção de uma boa noção do que são grafos direcionados ou dígrafos, basta
pensarmos no grafo de um bairro, onde temos como os vértices (nós) alguns pontos
do bairro e as arestas seriam as ruas, que interligam os pontos do bairro entre si. O
contexto de direcionado está no fator de mão e contramão, imaginemos que para
24
irmos da prefeitura da cidade que está localizada neste bairro, até o fórum, podemos
ir pela rua principal, mas para voltarmos à prefeitura, a mesma rua não é permitida,
pois é via de mão única, assim como uma aresta de um grafo direcionado, ela tem
sentido certo denominado. Vale ressaltar que nos grafos direcionados, as arestas
são substituídas por setas que indicam o vértice de destino e o sentido (direção) da
mesma.
Figura 4.0 – Grafo direcionado
Fonte: Adaptado pelo autor
Já o conceito de grafo não direcionado, ou apenas grafo, é justamente o oposto do
direcionado, pois as arestas não implicam em uma direção precisa de segmento, e
se pode associar a cada aresta um subconjunto de dois ou de um elemento de V
(conjunto de vértices), indicando as localidades finais.
Figura 5.0 – Grafo não direcionado
Fonte: Adaptado pelo autor
25
Outro tipo de grafo é o ponderado, para Ziviane (2005, p. 255), “um grafo ponderado
possui pesos associados às suas arestas”. Neste modelo, os valores que estão
associados influenciam nas decisões de escolha do caminho, pois os custos sobre
cada aresta podem variar. Este tipo de grafo é muito utilizado em problemas de
caminho mínimo, que visa à diminuição (otimização) de custos ao atravessar o grafo
na rota referida pelo problema.
10
A
B
15
22
D
C
35
Figura 6.0 – Grafo ponderado
Fonte: Adaptado pelo autor
Quando se tem um grafo simples e uma ligação associada a cada par de vértices, é
dito que o mesmo é completo. Este conceito é dado, pois ha uma ligação,
comunicação, entre todos os vértices, podendo se ir a qualquer parte do grafo
partindo de qualquer vértice.
As figuras abaixo (figura 7.0 e figura 8.0) distinguem bem um grafo simples de um
grafo completo. Lembrando que a diferença está em que, em um grafo simples não
se apresentam laços nem arestas paralelas, e o grafo completo é um grafo simples,
mas todos os vértices estão interligados.
Figura 7.0 – Grafo simples
Fonte: Adaptado pelo autor
Figura 8.0 – Grafo completo
Fonte: Adaptado pelo autor
26
2.3 ALGORITMOS
Para Said (2007, p. 07), algoritmo é “[...] uma sequência finita de passos, descritos
em uma ordem lógica, que visam a atingir um objetivo bem definido.”.
Resumindo, algoritmo é um passo a passo estruturado, finito, elaborado com o
intuito de se conseguir realizar um objetivo determinado, tarefa, cálculo, receita, etc.
A importância dos algoritmos é indiscutível, pois como o mesmo fora descrito
anteriormente, ele é uma sequência finita de passos, algo lógico para se atingir
determinada meta, o mesmo pode partir das primícias de uma bula de remédios até
áreas computacionais, matemáticas etc.
Um algoritmo pode ser feito (aplicado) geralmente de duas formas: gráfica, onde
para uma melhor visualização serão utilizados diagramas de blocos; e de forma
textual, onde será utilizada linguagem de programação.
Figura 9.0 – Algoritmos em diagrama de blocos
Fonte: BAJPAI; MUSTOE; VALKER
Matemática para engenheiros. (1980).
Figura 10.0 – Algoritmo textual
Fonte: Adaptado pelo autor
27
2.3.1 ALGORITMOS DE MENOR CAMINHO OU CAMINHO MÍNIMO
A definição de caminho é clara, está ligada na rota e na distância entre dois pontos,
um passeio sem vértices repetidos. Sabendo-se disso, é fácil entender que, a
distância de um vértice z, em um grafo G, até o vértice y, do mesmo grafo, é a soma
dos pesos das respectivas arestas existentes entre os dois vértices. Logicamente
admitindo que exista ligação entre os dois vértices.
Então, é correto dizer que K é o menor caminho entre z e y, caso não acha outros
caminhos.
Para verificar a existência de caminho entres dois vértices de um grafo, temos de
observar suas ligações (arestas).
Muito utilizado para determinado fim, é o algoritmo de Floyd-Warshall (ou Warshall).
Ele trabalha com a busca do caminho mais curto (entre os pontos de uma rota) de
um grafo dirigido e com pesos, valores (grafo valorado).
Figura 11.0 – Pseudocódigo do algoritmo de Warshall
Fonte: GOODRICH, TAMASSIA. Estrutura de dados e algoritmos em Java. (2007).
O algoritmo de Dijkstra foi criado por um cientista da computação holandês,
chamado Edsger Wybe Dijkstra (Roterdã, 11 de Maio de 1930 – Nuenen, 6 de
Agosto de 2002), aproximadamente no final da década de 50.
Goodrich e Tamassia (2007) relatam que, ao se tentar descobrir o caminho mais
curto de v a qualquer outro ponto do grafo, o algoritmo de Dijkstra é uma das
28
primeiras opções, pois como ele é considerado um método guloso, a sua aplicação é
tida como uma grande nuvem, que vai se expandindo e inserindo nela os vértices do
grafo, até não sobrar vértice algum de fora da nuvem. Tendo assim ao final do
processo, encontrado o menor caminho de v para qualquer outro vértice (nó) do
grafo.
Basicamente o algoritmo de Dijkstra funciona buscando e comparando os valores
(pesos) das arestas adjacentes ao vértice de origem, inicialmente deixando todos os
outros vértices com o custo “infinito”, ainda não descoberto. Conforme o algoritmo
vai avançando pelo grafo, o mesmo vai “marcando”, selecionando os vértices com
menores pesos, colocando neles “tarjas”, sinais, marcadores que podem ser
temporários ou definitivos, indicando as arestas de menor distancia entre o vértice
de origem até o vértice atual, sendo considerado um método guloso, pois vai
selecionando e escolhendo o menor caminho encontrado até o momento, lógico,
enquanto o algoritmo não chega ao fim. Chegando ao final do grafo, o algoritmo
assim, consegue identificar, o menor caminho entre os dois pontos (vértices) do
grafo. Pois terá obtido e marcado as arestas e vértices com menor custo.
Ressaltando que, o algoritmo de Dijkstra trabalha com grafos dirigidos ou não, e
ponderados com valores apenas positivos.
A tabela abaixo ilustra o funcionamento do algoritmo de Dijkstra através de uma
sequencia de diagramas.
Algoritmo de Dijkstra – Sequencia de Diagramas (Continua até pág. 30).
Inicialmente todos os nodos tem um custo
infinito,
exceto s (a raiz da busca) que tem valor 0:
vértices
s u v x y
∞∞∞∞
estimativas
0
precedentes
- - - -
-
29
selecione s (vértice aberto de estimativa
mínima)
feche s
recalcule as estimativas de u e x
vértices
s u v x y
∞
estimativas
0 10
precedentes
s s -
5
∞
s -
selecione x (vértice aberto de estimativa
mínima)
feche x
recalcule as estimativas de u,v e y
vértices
s u v x y
estimativas
0 8 14 5 7
precedentes s x x s x
selecione y (vértice aberto de estimativa
mínima)
feche y
recalcule a estimativa de v
vértices
s u v x y
estimativas
0 8 13 5 7
precedentes s x y s x
selecione u (vértice aberto de estimativa
mínima)
feche u
recalcule a estimativa de v
vértices
s u v x y
estimativas
0 8 9 5 7
precedentes s x u s x
30
selecione v (vértice aberto de estimativa
mínima)
feche v
vértices
s u v x y
estimativas
0 8 9 5 7
precedentes s x u s x
Tabela 1.0 – Sequencia de diagramas – Algoritmo de Dijkstra (Parte final da tabela - pág. 28, 29, 30).
Fonte: MARIANI – (Livro eletrônico) Site http://www.inf.ufsc.br/grafos/ (2012)
A figura 12.0 traz o pseudocódigo do algoritmo de Dijkstra, baseando no exemplo
dado do mesmo ser como uma nuvem, utilizando um recurso de “relaxamento de
aresta”, onde o relaxamento é dado por um caminho entre as arestas, ex (k, j),
tornando o relaxamento como uma espécie de mola, pois o mesmo vai se esticando
do ponto único de origem até o final, voltando ao ponto de partida, tendo assim o
resultado do melhor caminho.
Goodrich e Tamassia (2007) dizem que, seu principio básico é dado por:
Se D[u] + w((u, z)) < D[z] então
D[z] <- D[u] + w((u, z));
Onde D[u] é um rótulo, espécie de vetor ou pilha para cada vértice de u em V.
Figura 12.0 – Pseudocódigo do Algoritmo de Dijkstra – Relaxamento das arestas
Fonte: GOODRICH e TAMASSIA (2007).
31
2.3.3 ALGORITMO DE BELLMAN-FORD
O algoritmo de Bellman-Ford, criado por Richard Bellman e Lester Ford Jr, também é
um algoritmo de busca de caminho mínimo, basicamente sua diferença do Dijkstra, é
que, este aceita pesos negativos em suas arestas, enquanto o Dijkstra só aceita
valores positivos.
Levando-se em consideração o tempo gasto no processamento, o Dijkstra leva
vantagem, mas como dito antes, só trabalha com valores positivos em suas arestas.
Goodrich e Tamassia (2007) ressaltam que, devemos sempre buscar fazer com que
o grafo em que está sendo aplicado o algoritmo, deva ser um dígrafo (direcionado),
pois de outra forma (grafo não direcionado) poderíamos ir e vir por uma mesma
aresta, podendo ocorrer um loop (ciclo), deixando os pesos das arestas negativos, e
caso isso ocorra, se perderia o valor da distância entre os vértices, pois valores
negativos invalidam a noção de distância baseada no peso das arestas.
O algoritmo de bellman-ford, é mais fácil de ser compreendido e aplicado do que o
de Dijkstra. Tendo como exemplo o grafo da figura 13.0, é possível criar uma tabela
com os vértices de origem, destino e a distancia entre eles, criando uma maneira
mais didática para o entendimento da forma de aplicação e funcionamento do
algoritmo.
Figura 13.0 – Grafo orientado
Fonte: Adaptado pelo autor.
Origem
Destino
A
B
Distância
(Peso)
4
A
C
2
B
A
4
B
D
-5
C
A
2
C
E
3
D
C
8
E
D
-6
Tabela 2.0 – Tabela com os dados do grafo
da figura 13.0.
Fonte: Adaptado pelo autor.
32
O algoritmo de bellman-ford, baseia-se em:
Figura 14.0 – Pseudocódigo algoritmo de Bellman-ford
Fonte: GOODRICH, TAMASSIA. Projeto de Algoritmos: Fundamentos, análise e exemplos da
Internet. (2004).
Tendo como exemplo os dados da figura 13.0 e da tabela 2.0, a aplicação do
algoritmo de Bellman-ford (com a linguagem C/C++), se daria da seguinte maneira:
#include <iostream>
#define INFINITY 0x3f3f3f3f
#define NODOS 1000
using namespace std;
typedef struct {
int source;
int dest; //destino
int weigth; // peso
}Edge;
int distancia[NODOS];
void BellmanFord(Edge edges[], int edgecount, int nodecount, int source) {
33
int i,j,trocou;
for (i = 0; i < nodecount; i++) {
distancia[i] = INFINITY;
}
distancia[source] = 0;
for (i = 0; i < nodecount; i++) {
trocou = 0;
for (j = 0; j < edgecount; j++) {
if(distancia[edges[j].dest] > distancia[edges[j].source] + edges[j].weigth) {
distancia[edges[j].dest] = distancia[edges[j].source] + edges[j].weigth;
trocou = 1;
}
}
//se nenhuma iteração teve efeito, futuras iterações estão dispensadas
if (trocou == 0) break;
}
//usado somente para detectar ciclos negativos (dispensável)
for (i = 0; i < edgecount; i++) {
if (distancia[edges[i].dest] < distancia[edges[i].source + edges[i].weigth]) {
cout << "Ciclo negativo de pesos de arestas detectado" << endl;
break;
}
}
for (i = 0; i < nodecount; i++) {
cout << "A distancia mais curta entre os nodos " << source << " e " << i <<"
eh " << distancia[i] << endl;
}
}
int main(int argc, char *argv[])
{
34
//Este caso de teste produzira as distancias entre o nodo 0 e os outros nodos
Edge Arestas[8] = {{0, 1, 4}, {0, 2, 2}, {1, 0, 4}, {1, 3, -5},
{2, 0, 2}, {2, 4, 3}, {3, 2, 8}, {4, 3, -6}};
// BellmanFord(Estrutura,arestas,vertices,origem);
BellmanFord(Arestas,8,5,0);
system("PAUSE");
return 0;
}
2.4 ANÁLISE DE ALGORITMOS
Análise de Algoritmos é uma importante área da Ciência da Computação onde são
estudados os recursos e ou tempo necessários para a execução de um determinado
algoritmo.
Ziviane(2005, p. 03) relata que:
Depois que um problema é analisado e decisões de projeto são finalizadas,
o algoritmo tem de ser implementado em um computador. Neste momento,
o projetista tem de estudar as várias opções de algoritmos a serem
utilizados, em que os aspectos de tempo de execução e espaço ocupado
são considerações importantes.
Quando o tema em análise de algoritmos é Medida do Tempo de Execução de um
Programa, é preciso se preocupar ou ficar atento em pelo menos dois tipos distintos
de problemas quando, for feita a análise de um algoritmo em particular e a análise
de uma classe de algoritmos.
Knuth (apud Ziviane, 2005, p. 03) aborda que na análise de um algoritmo em
particular, é necessário saber qual é o custo de usar um dado algoritmo para
resolver um problema específico, que neste caso deverão ser investigadas as
características importantes do algoritmo em questão (número de vezes que cada
parte do algoritmo deve ser executada). Já na análise de uma classe de algoritmos,
35
devemos nos atentar para a seguinte pergunta: qual é o algoritmo de menor custo
possível para resolver um problema particular? Geralmente neste tipo de análise,
toda uma estrutura (família) de algoritmos destinados ao mesmo tipo de problema
deve ser analisada.
Algumas técnicas e ou maneiras são utilizadas para medirmos o custo de utilização
de um algoritmo. A implementação do mesmo (algoritmo em questão) em um
computador real, seria uma das maneiras para a medição do custo de utilização
(método empírico). Mas será que os dados obtidos por este tipo de medição, seriam
precisos?
Partindo do pressuposto que o algoritmo deveria ser ótimo (trabalhar conforme o
esperado ou seu custo ser menor ou igual ao custo possível) sem interferências de
fatores não correlatos, é correto afirmar que, não poderemos ter uma medição
precisa, já que vários fatores poderiam influenciar, tais como: quantidade de
memória, processador, compilador utilizado, etc.
Para encontrarmos meios mais contundentes e adequados, precisamos utilizar
métodos matemáticos, definindo o número de operações a serem executadas e o
custo de cada operação (complexidade dos algoritmos). No final se compararmos
algoritmos destinados à resolução de um mesmo tipo de problema, com algum custo
estimado e ou esperado, podemos então ter uma base de qual algoritmo teve um
desempenho melhor. Ou ainda podemos considerar ou analisar, como foi
mencionado anteriormente, somente as partes mais relevantes do código, como os
loops, abstraindo assim as outras partes (como atribuição).
2.4.1 COMPLEXIDADE DOS ALGORITMOS - ANÁLISE ASSINTÓTICA
Segundo Merdina e Fertig (2006) os algoritmos podem ter sua classificação definida
pelo tipo de expressão matemática que defini seu comportamento na análise de
complexidade. Para isso se utiliza o comportamento assintótico da função do tempo
“T” em relação ao tamanho da entrada do algoritmo (n).
36
O tempo de resposta de um algoritmo está intrinsicamente ligado ao tamanho da
entrada dos dados (n) e também a forma como os dados são inseridos (melhor caso,
pior caso e resultado esperado ou estimado).
A análise assintótica ignora constantes dependentes da máquina e olha em vez do
tempo real de execução, o crescimento do tempo de execução T(n).
Basicamente, é correto afirmar que, a análise assintótica não define expressamente
o número total de passos e ou operações que um algoritmo fará, mas ilustra o
comportamento que o mesmo terá quando variamos o valor da entrada dos dados
(n).
A classe assintótica é representada também pela notação O.
Merdina e Fertig (2006) apontam algumas classes com esta notação:
Constante: O(1)
Logarítmica: O(lg(n)) (representamos logaritmo na base 2 como lg)
Linear: O(n) (lê-se “O de n” ou “Ordem de n”)
Quadrática: O(n²)
Cúbica: O(n³)
Exponencial: O(cn), onde c é uma constante.
Tendo como base as informações dadas neste tópico, vamos tentar analisar um
simples algoritmo que trabalhe em função da resposta de uma simples somatória:
O pseudocódigo para este algoritmo ficaria assim:
Inicio
somatoria numérico;
somatoria  0;
para i  2 até n faça
somatoria  somatoria + i*i*i*i*i*i;
fimpara
37
escreva(somatoria);
fim
Se hipoteticamente atribuíssemos para operações simples como atribuições, somas,
multiplicações, etc., o valor de 01 unidade de tempo, o valor assintótico deste
algoritmo, seria algo em torno de 6n+4, ou seja, uma equação linear, portanto O(n).
Tentar atribuir um valor com exatidão, como foi o caso do pseudocódigo anterior,
nem sempre é possível, por isso como mencionado anteriormente, a Análise
Assintótica não procura mostrar o número exato de passos ou tempo que um
algoritmo levará para executar determinada tarefa, mas sim o valor assintótico do
mesmo quando o valor da entrada dos dados (n) variar ou tender ao
∞(infinito).
Quando passamos a analisar o valor da entrada (n) em sua forma assintótica
(tendendo ao infinito) dentro de, por exemplo, a denotação O, podemos ter com mais
clareza a velocidade, ou melhor, tempo de resposta de um determinado grupo de
algoritmos. Não dependendo assim de fatores referentes à máquina (memória,
compilador, processador, etc.).
Para uma maior clareza, vamos pensar em dois algoritmos que servem para a
mesma tarefa, onde o algoritmo A tem o tempo de resposta 350n + 550, e o
algoritmo B 3n² + 20n + 3. A princípio, com entradas pequenas, o algoritmo B levará
certa vantagem quanto ao A, ex:
Valor de T(n) = 3;
A = 350 * 3 + 500 = 1550; O(n)
B = 3*3² + 20 * 3 + 3 = 90; O(n²)
Mas quando pensamos no valor de (n) subindo assintóticamente, claramente o
algoritmo A executará uma menor quantidade de tarefas para satisfazer todas as
operações do algoritmo, ex:
Valor de T(n) = 300;
A = 350 * 300 + 500 = 105500; O(n)
B = 3 * 300² + 20 * 300 + 3 = 276003; O(n²)
38
Ainda observando os exemplos acima, pode-se notar que um algoritmo de equação
linear sempre será mais rápido que um algoritmo quadrático, pois em algum ponto
(n0) o algoritmos quadrático ultrapassará o linear, assim como um O(log(n)) será
mais rápido que um linear. E também é válido dizer que, a análise assintótica
dispensa os termos de menor valor, pois os mesmos não influenciam de maneira
significativa no resultado final. Sendo assim, em um algoritmo de equação 5n² + 20n
+ 6, somente será levado em consideração o maior termo, no caso 5n², logo teremos
a denotação O(n²) para tal algoritmo.
A figura 15.0 mostra com mais clareza como algoritmos de diferentes notações se
comportam quando a entrada (n) é variada, independentemente se o computador
que o algoritmo de maior ordem esteja rodando seja algumas vezes mais rápido que
o outro algoritmo. Neste exemplo, pode-se observar que, em algum ponto quando a
marca do n0 é assintoticamente alta, o algoritmo de proporção f(n) passa ser a
melhor escolha.
Figura 15.0: Análise Assintótica
Fonte: GOODRICH, TAMASSIA. Estrutura de dados e algoritmos em Java. 4. ed. ( 2007).
É válido ressaltar que, dependendo do tamanho da entrada e a forma como a
mesma é inserida, muitas vezes poderemos optar por um algoritmo de ordem maior,
pois seu rendimento inicial, quando o valor de n ainda é pequeno, ou seja, não
atingiu o ponto n0, pode ser mais rápido que o algoritmo de menor ordem.
39
2.4.2 PROGRAMAÇÃO LINEAR
Segundo Gomes e Ribeiro (2004, p. 59) “a programação linear lida basicamente com
o problema de alocar recursos escassos a atividades que por eles “competem” entre
si, e cujo modelo se representa por meio de expressões lineares”.
Uma observação válida é que, o termo programação, não diz respeito à
programação de computadores, mas sim a planejamento, estrutura de ajuda a
decisões, como alocar melhor os recursos disponíveis.
Como base para uma melhor compreensão, será abordado um caso hipotético onde
uma Empresa pretende otimizar sua produção mensal de cadeiras e mesas,
visando, logicamente, diminuir seus custos e maximizar os lucros. Sabendo-se que,
cada mesa precisa de 6 horas de carpintaria e 4 horas de pintura, as cadeiras
precisam de 4 horas de carpintaria e 2 horas de pintura. Durante o período
analisado, há disponível 240 horas-homem de carpintaria e 100 horas/homem de
pintura. Cada mesa lucra R$ 7,00 e cada cadeira R$ 5,00.
Montando os dados em uma tabela temos:
Horas para produzir 01 unidade
Departamento
Horas
Mesas (M)
Cadeiras (C)
Carpintaria
6
4
240
Pintura
4
2
100
Lucro unitário
7
5
disponíveis
Tabela 3.0 – Exemplo PL
Fonte: Adaptado pelo autor
Depois de modelados os dados em uma tabela e já sabermos o que a empresa
procura (otimizar custos e maximizar lucros), temos de observar os recursos
escassos ( horas disponíveis).
Agora é necessário observar, qual produto deverá ser utilizado, produzido, em
detrimento de outro. Exemplo será que devemos produzir mais mesas? Isso
40
consequentemente exigiria mais madeira e tempo, o que deixaria as mesas com
menor uso de tais recursos.
Segundo Chase, Jacob e Aquilano (2006, p. 665) “quando um único objetivo deve
ser maximizado (como o lucro) ou minimizado (como os custos), pode-se utilizar a
programação linear”.
Utilizando a formula para Maximizar (Z = C1X1 + C2X2 + ... + CnXn ou
) e aplicando os dados informados pelo problema, obteremos o
valor de Z (Maximização dos lucros), logicamente substituindo os valores de C1X1 ...
pelos valores reais de cadeiras (C) e mesas (M).
Logo a função para maximização seria 7M + 5C, ou seja, a quantidade de mesas x
R$ 7,00 + a quantidade de cadeiras x R$ 5 reais.
Observando as restrições implícitas pelo problema (tempo de carpintaria 240h,
tempo de pintura 100h), sabemos que, cada mesa gasta 6h e cada cadeira 4h, logo
temos a inequação de 6M + 4C <= 240. Fazendo o mesmo processo para a pintura,
temos a inequação 4M + 2C <= 100.
Conclui-se portanto que, para todo M,C >= 0, focando a maximização dos lucros 7M
+ 5C, temos as restrições 6M + 4C <= 240 e 4M + 2C <= 100. Resolvendo assim de
forma linear o problema.
Imaginando um quadro também hipotético, onde precisaríamos modelar um cenário
de mapa rodoviário onde sua estrutura construída em grafos pode ser de proporções
gigantescas, e a necessidade de aplicar isso em um espaço ou tela de forma
otimizada, priorizando algo (qualidade da imagem, por exemplo) e observando as
restrições (tamanho da tela), o estudo desta resposta pela programação linear se
torna algo interessante.
Resumindo, como relata Chase, Jacob e Aquilano (2006, p. 665) “a programação
linear reúne às várias técnicas matemáticas utilizadas para alocar os recursos
limitados entre as demandas competitivas de uma maneira ótima”.
41
2.4.3 ALGORITMO ESCOLHIDO
A tabela 3.0 descreve o tempo de resposta (complexidade algorítmica) dos
algoritmos pesquisados para a conclusão da referente pesquisa.
AUTORES
DESCRIÇÃO
COMPLEXIDADE
Algoritmo utilizado em
buscas de menor
Bellman-Ford
caminho, diferenciado
O(va)
pois aceita pesos
negativos nas arestas.
Algoritmo utilizado em
Floyd-Warshall
buscas de menor caminho
em grafos orientados e
O(n³)
valorados.
Algoritmo utilizado em
buscas de menor caminho
Dijsktra
em uma rota, partindo de
um ponto qualquer, sendo
O(n²)
considerado um algoritmo
guloso.
Tabela 4.0 – Complexidade dos algoritmos
Fonte: Adaptado pelo autor.
Com base nas informações adquiridas através das pesquisas realizadas para este
projeto, foi utilizado para a conclusão do mesmo o algoritmo de Dijkstra. O qual
melhor se enquadra para resolução do problema proposto por esta pesquisa, visto
que, o algoritmo trabalha com pesos positivos nas arestas dos grafos, e tem uma
resposta mais rápida (O(n²)) quando se comparado aos demais algoritmos
abordados neste projeto.
42
2.5
FERRAMENTAS
(IDE’s)
E
LINGUAGEM
UTILIZADAS
NO
DESENVOLVIMENTO DO SOFTWARE
2.5.1 C#
O C# (leia-se Cê charp ou C Sharp) é uma linguagem orientada a objetos criada
pela Microsoft (baseada nas linguagens C, C++ e Java), trabalha juntamente com
sua plataforma .Net.
Sharp (2008) relata que o C# é uma poderosa linguagem orientada para
componentes da Microsoft, e que para um usuário com alguma experiência em
outras linguagens orientadas a objetos como C++ e Java, a sua assimilação com a
sintaxe e com o modo de trabalhar com a mesma será rápida.
O protótipo foi desenvolvido com a utilização da linguagem C# juntamente com o kit
de
desenvolvimento
Microsoft
Visual
C#
2008
Express
(kit
gratuito
de
desenvolvimento de aplicativos, criado pela Microsoft, com o intuito de auxiliar os
programadores que trabalham com a linguagem C#).
A escolha desta linguagem e IDE para o desenvolvimento do aplicativo se dá pelo
fato de as mesmas terem sido usadas em algumas disciplinas estudadas durante a
graduação.
2.5.2 UML - UNIFIED MODELING LANGUAGE OU LINGUAGEM DE MODELAGEM DE DADOS
Para uma melhor visualização de algumas funções e operações do software
desenvolvido nesta pesquisa, foi utilizada como técnica de modelagem dos dados a
UML.
Segundo Booch, Rumbauch e Jacobson (2005, p. 13), “a UML, Linguagem Unificada
de Modelagem, é uma linguagem gráfica para visualização, especificação,
construção e documentação de artefatos de sistemas complexos de software”.
43
Booch, Rumbauch e Jacobson (2005), descrevem que a UML surgiu por volta da
metade da década de 90, quando Booch, Jacobson e Rumbauch, perceberam que
seus trabalhos anteriores (Rational Software Corporation, Objectory e General
Electrics) estavam interligados de forma natural e progressiva, só lhes restando
assim, juntarem os esforços e abstraírem o melhor de cada ideia.
44
3.0 IMPLEMENTAÇÃO DIJKSTRA – PROTÓTIPO
3.1 DIAGRAMA DE CASO DE USO
Segundo Medeiros(2004), um caso de uso é uma representação de diversas,
variadas ações, as quais representam uma macroatividade.
A figura 16.0 mostra com um caso de uso, uma visão macro do Protótipo criado
nesta pesquisa.
Figura 16.0 – Diagrama de Caso de Uso – Protótipo
Fonte: Adaptado pelo Autor.
Como observado na figura 16.0, o funcionamento do software é bem simples e
objetivo, buscando mostrar na prática, o funcionamento do algoritmo de Dijkstra.
No primeiro processo o usuário irá indicar qual o tipo de grafo que o algoritmo
deverá trabalhar, e isso também influenciará na forma como as pontas das arestas
serão desenhadas pelo software. Em seguida o usuário irá criar as cidades (nós),
depois estabelecer as ligações existentes entre as mesmas e o peso (a distancia)
45
nas arestas equivalentes entre um nó e outro. Após estes processos, deverá ser
informado pelo usuário, o ponto de partida (origem) em que o algoritmo deverá
começar a buscar as menores rotas, e por último, o usuário inicia o software,
deixando todos os cálculos e processos necessários para obter a menor, ou melhor,
rota, incumbidos ao programa, onde uma vez finalizados os processos, o software
retornará, as menores distâncias entre todos os pontos do grafo, partindo do ponto
de origem informado pelo usuário.
3.1.2 DIAGRAMA DE ATIVIDADES
Os diagramas de atividades tem basicamente por função, mostrar as execuções,
tarefas e ou atividades que ocorrem entre uma atividade e outra.
Para um melhor entendimento e compreensão de algumas funcionalidades do
protótipo, foi elaborado um diagrama de atividades (figura 17.0), baseado no
processo de executar o algoritmo de Dijkstra no software, onde após a inserção dos
dados pelo usuário e acionado a funcionalidade do algoritmo, o mesmo começa a
fazer uma varredura dos dados, analisando-os e checando possíveis erros nos
dados inseridos, como peso negativo das arestas, falta de ligação entre os vértices
(nós), quantidade de nós insuficientes.
46
Figura 17.0 – Diagrama de Atividades – Executar Dijkstra
Fonte: Adaptado pelo autor
3.1.3 DIAGRAMA DE SEQUÊNCIA
Segundo Medeiros (2004, p. 147),
este diagrama pode ser usado para mostrar a evolução de uma dada
situação em determinado momento do software, mostrar uma dada
colaboração entre duas ou mais classes e pode, também, ser usado para
mostrar a tradução de um Caso de Uso desde a interação com o usuário até
a finalização daquele dado processo.
47
A figura 18.0, ilustra o diagrama de sequência do processo de execução do
algoritmo de Dijkstra. Onde o mesmo complementa o diagrama de atividades,
proporcionando assim, um melhor entendimento deste processo.
Figura 18.0 – Diagrama de sequência
Fonte: Adaptado pelo autor
3.1.4 DIAGRAMA DE CLASSES
Para representar as relações e os conceitos entre as classes que fazem parte de um
sistema, dá-se a elaboração de um diagrama de classes.
48
O protótipo apresentado neste projeto foi desenvolvido utilizado programação
orientada a objetos. Para um melhor acompanhamento e entendimento do código,
foi criado o diagrama de classes de parte do código.
Figura 19.0 – Diagrama de classe
Fonte: Adaptado pelo autor
3.2 GRAFO DE ESTUDOS – PROTÓTIPO
A imagem a seguir mostra o grafo que está pré-fixado no código do programa, se
baseando nele que foi testado, abordado e estudado o funcionamento do algoritmo
em questão (Dijkstra).
49
Figura 20.0 – Grafo pré-disposto do protótipo
Fonte: Adaptado pelo autor
3.3 PROTÓTIPO
A figura abaixo mostra a tela inicial do protótipo, onde tanto os dados de entrada,
assim como os de respostas, serão mostrados.
É nesta tela que todo o controle das informações que serão utilizadas (como tipo de
grafo (direcionado ou não), forma como os dados serão inseridos, tipo de inserção
de
dados
(manual
ou
não),
etc.)
é
administrado.
No lado direito, no pequeno espaço branco, abaixo do label Melhor caminho.:, serão
mostrados os nomes das cidades que farão parte da menor rota do grafo elaborado.
50
Figura 21.0 – Protótipo – Tela Principal
Fonte: Adaptado pelo autor
Na parte inferior da tela principal, é possível observar alguns botões, combobox,
textbox e radiobuttons, onde que, para uma correta funcionalidade do software, é
imprescindível que acha um controle correto sobre os mesmos.
Figura 21.1 – Protótipo – Tela Principal – Parte inferior
Fonte: Adaptado pelo autor
Dentro de cada combobox está a lista de cidades que estão pré-dispostas no
programa (figura 20.0), onde o usuário deverá selecionar uma cidade como origem e
outra como destino. Depois de selecionadas as cidades o usuário deverá clicar no
51
botão Dijkstra para que o programa execute o algoritmo que fará a busca pela
melhor rota entre as duas cidades selecionadas.
O botão Habilitar forma manual (ver figura 21.1) quando pressionado, habilita a
forma manual de inserção dos dados, onde fica por inteira responsabilidade do
usuário que todos os dados inseridos, estejam de forma correta, para que não haja
falha ou erros no processo de busca de menor rota.
Após todos os processos de inserção de dados, (modo manual), e pressionado o
botão Dijkstra, a parte branca da tela principal, deverá mostrar em cada nó, o valor
do seu menor caminho entre ele e o nó principal (origem), isso acontece, pois como
explicado anteriormente nesta pesquisa, o algoritmo de Dijkstra é um método
guloso, ou seja, ele não calcula somente o melhor caminho entre dois pontos de um
grafo, mas sim, o melhor caminho entre o nó principal e os demais nós do grafo,
tornando assim, cada resultado apresentado nos nós, o melhor ou menor caminho
existente.
Figura 21.2 – Protótipo – Simulação entrada de dados manualmente
Fonte: Adaptado pelo autor
52
3.3.1 IMPLEMENTAÇÃO DO ALGORITMO DE DIJKSTRA EM C SHARP
O código abaixo é parte principal ou pelo menos um pedaço dela, do algoritmo
responsável pela otimização da busca das menores rotas. O código está adaptado
para a linguagem escolhida. Tomei o cuidado de comentar os passos envolvidos
neste trecho do código, para uma melhor compreensão do mesmo.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Dijkstra
{
class Dijkstra
{
//Variáveis (vetores) para armazenamento da distância e caminho de cada nó
(vértice)
public double [] distancia;
public int [] caminho;
//Lista para armazenar os nós ainda não checados pelo algoritmo
private List<int> lista_nos = new List<int>();
//Função de inicialização
public void Inicializar(int comeco, int tamanho)
{
distancia = new double[tamanho];
caminho = new int[tamanho];
for (int i = 0; i < tamanho; i++)
{
distancia[i] = Double.PositiveInfinity; //Preenchendo com valores positivos
"infinitos"
lista_nos.Add(i); //Adicionando nós na lista ^^
}
/*Aqui, estou colocando o valor 0(zero) para o ponto inicial
e nulo (-1) para os caminhos anteriores */
distancia[comeco] = 0;
caminho[comeco] = -1;
}
53
private int proximoVertice()
{
double min = Double.PositiveInfinity;
int Vertex = -1;
//Procurando na lista pelas menores rotas (pesos nas arestas)
foreach (int j in lista_nos)
{
if (distancia[j] <= min)
{
min = distancia[j];
Vertex = j;
}
}
lista_nos.Remove(Vertex); // Retira da lista o menor vértice encontrado
return Vertex; // Retorna o vértice de menor valor encontrado naquela busca
}
//Método construtor
public Dijkstra(double[,] G, int comeco)
{
int pNegativos = 0;
//Só pra nível de observação, para não dá erro no algoritmo
//... verificando se o grafo contém algo,
//e se contém pelo menos 2 vértices (Matrix de adjacencia ...então N x N ...
colunas = linhas)
if (G.GetLength(0) < 1 || G.GetLength(0) != G.GetLength(1))
{
MessageBox.Show("Erro no gráfico", "Error", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
else
{
int tamanho = G.GetLength(0); //Instancio o tamanho que deverá ter os
meus vetores (caminho e distancia)
Inicializar(comeco, tamanho);
while (lista_nos.Count > 0)
{
int u = proximoVertice();
/* Laço inicial para a busca das conecções dos vértices */
for (int v = 0; v < tamanho; v++)
54
{
/* Checando se tem pesos negativos ligados nos vértices */
if ((G[u, v] < 0) && (pNegativos == 0))
{
MessageBox.Show("O Grafo contém pesos negativos", "Erro Pesos Negativos", MessageBoxButtons.OK, MessageBoxIcon.Error);
pNegativos = 1;
}
/* Verifica se existe alguma ligação (aresta) entre os nós em
questão*/
if ((G[u, v] > 0) && (pNegativos == 0))
{
/* Se existir, fazer o relaxamento da aresta*/
if (distancia[v] > distancia[u] + G[u, v])
{
distancia[v] = distancia[u] + G[u, v];
caminho[v] = u;
}
}
}
}
}
}
}
}
55
4.0 CONCLUSÃO E RECOMENDAÇÕES
4.1 CONCLUSÃO
Diminuir custos e aumentar a velocidade das respostas são fatores constantemente
analisados e trabalhados para obtenção de êxito em ambos.
Em problemas de menor caminho entre dois pontos de um grafo valorado, com
pesos apenas positivos, observou que o algoritmo de Dijkstra juntamente com a
linguagem C#, obteve o desempenho, por esta pesquisa, esperado.
Após pesquisar e analisar os valores assintóticos de vários algoritmos, e colocar em
prática o qual se mostrou o melhor (algoritmo de Dijkstra), foi constato que a
utilização de algoritmos que trabalham com grafos, traz um desempenho favorável.
É nítida a otimização de tempo nas respostas.
Empresas de transportes, autônomos, taxistas e afins, que trabalham no ramo de
transportes e fretes, trabalhando com softwares do mesmo gênero, poderiam
diminuir os custos com combustível, pois saberiam antes da jornada de trabalho, o
menor caminho a seguir.
4.2 RECOMENDAÇÕES
Recomendo que este projeto seja trabalhado mais amplamente, podendo o mesmo
ser migrado para plataformas Mobiles, onde suas atualizações poderiam ser feitas
através de uma base de dados, a qual conteria informações de diversas cidades e
suas distancias entre si. Também tendo uma opção onde o usuário entraria com a
informação do consumo do seu automóvel (Km/l), e ao final do processo, o software
além de trazer a menor rota, também indicaria quantos litros de combustível,
aproximadamente, o usuário iria gastar naquela viagem. Trazendo assim um
conforto e praticidade aos profissionais do ramo de transporte (taxistas, autônomos,
etc.). Pois o funcionamento desde protótipo, não se baseia em como chegar a um
56
determinado local, mas sim, quais são os melhores ou menores caminhos a seguir
para chegar lá.
57
5.0 REFERÊNCIAS BIBLIOGRÁFICAS
1.
ANDRADE, Maria Margarida de. Introdução à metodologia do trabalho
científico: elaboração de trabalhos na graduação. 5. ed. São Paulo: Atlas, 2001.
2.
BAJPAI, Avi C.; MUSTOE Leslie R.; VALKER, Dennis. Matemática para
engenheiros. São Paulo: Hemus-Livraria Editora Ltda. 1980.
3.
BONCHEV, Danail; ROUVRAY, Denni H. Chemical Graph Theory:
introduction and fundamentals. 1. ed. Amsterdam: Gordon and Breach Science
Publishers S.A, 1991.
4.
CHASE,
Richard
B.;
JACOBS
F.
Robert;
AQUILANO,
Nicholas
J.
Administração da produção para a vantagem competitiva. Porto Alegre:
Bookman, 2006.
5.
DEWDNEY, A.K. 20.000 léguas matemáticas: um passeio pelo misterioso
mundo dos números / A.K. Dewdney. Rio de Janeiro: Jorge Zahar Ed., 2000.
6.
GIL, Antonio Carlos. Como Elaborar Projetos de Pesquisa. 4.ed. São Paulo:
Atlas,2007.
7.
GOLDBARG,
Marco
Cesar;
LUNA,
Henrique
Pacca
L.
Otimização
combinatória e programação linear. 2. Ed. Rio de Janeiro: Elsevier, 2005.
8.
GOMES, Carlos Francisco Simões; RIBEIRO, Priscila Cristina Cabral. Gestão
da Cadeia de Suprimentos integrada à Tecnologia da Informação. São Paulo :
Pioneira Thomson Learning, 2004.
9.
GOODRICH, Michael T; TAMASSIA, Roberto. Estrutura de dados e
algoritmos em Java. 4. ed. – Porto Alegre : Bookman, 2007.
58
10.
GOODRICH, Michael T; TAMASSIA, Roberto. Projeto de Algoritmos:
Fundamentos,
análise
e
exemplos
da
Internet.
Porto
Alegre:
Bookman
CompanhiaEd, 2004.
11.
do
MARIANI, Antonio Carlos. Livro eletrônico: Algoritmo de Dijkstra para cálculo
Caminho
de
Custo
Mínimo.
Disponível
em
http://www.inf.ufsc.br/grafos/temas/custo-minimo/dijkstra.html (Acessado em maio de
2012).
12.
MEDEIROS, Ernani Sales de. Desenvolvendo software com UML 2.0:
definitivo. São Paulo: Pearson Makron Books, 2004.
13.
MEDINA, Marco; FERTIG, Cristina. Algoritmos e programação: teoria e
prática. São Paulo: Novatec Editora, 2006.
14.
MERTENS, Roberto S. Kahlmeyer; FUMANGA, Mario; TOFFANO, Claudia
Benevento; SIQUEIRA, Fabio. Como elaborar projetos de pesquisa: Linguagem e
método. 1. ed. Rio de Janeiro: FGV, 2007.
15.
OLIVEIRA, Tereza Farias de; NUNES, Márcia Vidal. Cidadania e cultura
digital: apropriações populares da Internet. Rio de Janeiro: E-papers, 2011.
16.
REIS, Linda G. Produção de monografia da teoria à prática / Linda G. Reis.
2. ed.Brasília : Senac-DF, 2008.
17.
RICHARDSON, Robert Jarry. Pesquisa social: métodos e técnicas. São
Paulo:Atlas, 1999.
18.
SAID, Ricardo. Curso de Lógica de Programação. São Paulo: Digerati
Books, 2007.
19.
SHARP, John. Microsoft Visual C# 2008: passo a passo / John Sharp. Porto
Alegre : Bookman, 2008.
59
20.
VERGARA, Sylvia Constant. Projetos e relatórios de pesquisa em
administração. 4. ed. São Paulo: Atlas, 2003.
21.
ZIVIANE, Nivio. Projeto de algoritmos: com Implementações em Pascal e C.
2. ed. rev. e ampl. São Paulo: Pioneira Thomson Learning, 2005.

Documentos relacionados

Visualizar - Polis Educacional

Visualizar - Polis Educacional making reference the two algorithms in special, that they are Dijkstra and Bellman-Ford, and this last having the option to calculate routes in graphs with arcs of negative value, however, not used...

Leia mais