Você está na página 1de 82

UNIVERSIDADE TECNOLÓGICA FEDERAL DO PARANÁ

CESAR EDUARDO KAORU ARRUDA


FLÁVIO MOISÉS DE ARAÚJO

SERVIÇO DE ROTEIRIZAÇÃO VIA WEB


PARA DISPOSITIVOS MÓVEIS

CURITIBA

2007
UNIVERSIDADE TECNOLÓGICA FEDERAL DO PARANÁ

CESAR EDUARDO KAORU ARRUDA


FLÁVIO MOISÉS DE ARAÚJO

SERVIÇO DE ROTEIRIZAÇÃO VIA WEB


PARA DISPOSITIVOS MÓVEIS

Trabalho de Diplomação apresentado


como requisito para a formação no Curso
Superior de Tecnologia em Informática,
da Universidade Tecnológica Federal do
Paraná.
Orientador: Prof. Doutor Gustavo Alberto
Gimenez Lugo.

CURITIBA

2007
Cesar Eduardo Kaoru Arruda
Flávio Moisés de Araújo

SERVIÇO DE ROTEIRIZAÇÃO VIA WEB PARA DISPOSITIVOS


MÓVEIS

Este Trabalho de Conclusão de Curso foi julgado e aprovado para obtenção do


título de Tecnólogo em Informática, da Universidade Tecnológica Federal do
Paraná – Campus Curitiba.

Curitiba, 25 de junho de 2007

Prof. Wânia M. M. Figueredo


Coordenadora do Curso de Tecnologia em Informática
DAINF-CT / UTFPR

Prof. Dra. Gilda M. S. Friedlaender


Coordenadora da Disciplina de TCC
DAINF-CT / UTFPR

Banca Examinadora

Prof. Doutor Gustavo Alberto Gimenez Lugo


Orientador
DAINF-CT / UTFPR

Prof. Doutor Cesar Augusto Tacla


DAINF-CT / UTFPR

Prof. Christian Carlos Souza Mendes


DAINF-CT / UTFPR

iii
RESUMO

A proposta deste projeto é um sistema roteirizador projetado para celulares,


que execute via web. Tal sistema baseia-se em um site WAP no qual o usuário
informa sua localização de origem e o ponto de destino almejado, obtendo como
resposta a melhor forma de atingir seu objetivo entre as opções 'a pé', 'de carro'
ou 'de ônibus'. A resposta apresentada é uma seqüência de indicações
geográficas (Ex.: Pegue o ônibus Capão Raso-Santa Cândida no ponto Passeio
Público, pare no ponto Eufrásio Corrêia, siga 2 quadras pela Avenida Sete de
Setembro até o número 3550, etc). Pela dificuldade de se obter os dados
necessários para o projeto (nomes de ruas, numeração das ruas, linhas de ônibus,
etc), o escopo geográfico do roteirizador foi definido como sendo somente o bairro
Centro de Curitiba. Devido ao uso de softwares e tecnologias open source, os
custos do projeto resumiram-se a eventuais gastos rotineiros. O projeto foi
desenvolvido entre os períodos de Setembro de 2006 e Maio de 2007.

iv
ABREVIATURAS, SIGLAS E ACRÔNIMOS

HTML = HyperText Markup Language


ISO-8859-1 = International Organization for Standardization
JDK = Java Development Kit
JSP = Java Server Pages
MMS = Multimedia Messaging Service
NMIT = Nokia Mobile Internet Toolkit
OSS (Open Source System) = Sistema de Código Aberto
PDA = Personal Digital Assistant
SGBD = Sistema Gerenciador de Banco de Dados
SMIL = Synchronized Multimedia Integration Language
URL = Uniform Resource Locator
UTF-8 = Unicode Transformation Format
WAP = Wireless Application Protocol
WBMP = Wireless Bitmap
WML = Wireless Markup Language
WMLScript = Wireless Markup Language Script

v
SUMÁRIO

RESUMO.................................................................................................................iv
ABREVIATURAS, SIGLAS E ACRÔNIMOS .......................................................... v
SUMÁRIO ...............................................................................................................vi
ÍNDICE DE FIGURAS ........................................................................................... viii
ÍNDICE DAS TABELAS.......................................................................................... x
1. INTRODUÇÃO .................................................................................................... 1
1.1 TEMA ................................................................................................................ 1
1.2 JUSTIFICATIVAS DO PROJETO...................................................................... 2
1.3 OBJETIVOS ...................................................................................................... 5
1.3.1 Criação do Site WAP...................................................................................... 5
1.3.2 Desenvolvimento de um Algoritmo de Roteirização ....................................... 5
1.3.3 Sistema eficiente e simples ............................................................................ 6
1.4 REQUISITOS DO SISTEMA ............................................................................. 7
1.5 FUNCIONAMENTO DO SISTEMA.................................................................... 8
2. ESPECIFICAÇÃO DO SISTEMA...................................................................... 10
2.1 DIAGRAMA DE CASOS DE USO ................................................................... 10
2.2 MODELO DE DADOS ..................................................................................... 11
2.2.1 Modelo Entidade Relacionamento................................................................ 11
2.2.2 Dicionário de Dados ..................................................................................... 13
2.3 LEVANTAMENTO DE CLASSES.................................................................... 15
2.4 DIAGRAMA DE CLASSES.............................................................................. 16
2.5 DIAGRAMA DE SEQÜÊNCIA ......................................................................... 17
3. TECNOLOGIAS E ALGORITMOS ................................................................... 20
3.1 JSP E SERVLETS........................................................................................... 20
3.2 TOMCAT ......................................................................................................... 21
3.3 POSTGRESQL E PGADMIN........................................................................... 21
3.4 WAP ................................................................................................................ 22
3.5 WML E WMLSCRIPT ...................................................................................... 23
3.6 NOKIA MOBILE INTERNET TOOLKIT (NMIT) ............................................... 24

vi
3.7 ALGORITMO DE DIJKSTRA........................................................................... 24
3.8 ALGORITMO DE FLOYD-WARSHALL ........................................................... 25
4. FERRAMENTAS DE DESENVOLVIMENTO .................................................... 27
4.1 ARQUITETURA DO SISTEMA........................................................................ 27
4.2 WML E JSP ..................................................................................................... 28
4.3 SERVLET ........................................................................................................ 30
4.4 WAP ................................................................................................................ 32
5. ANÁLISE DOS ALGORITMOS......................................................................... 36
5.1 EXEMPLO DE GERAÇÃO DE BANCO E CÁLCULO DE ROTEIRIZAÇÃO.... 36
5.1.1 Geração do banco de dados e roteirização: Floyd-Warshall ........................ 37
5.1.2 Geração do banco de dados e roteirização: Dijkstra.................................... 39
5.1.3 Geração do banco de dados e roteirização: BuscaCuritiba.......................... 42
5.2 CASOS DE TESTES ....................................................................................... 42
6. DESENVOLVIMENTO DO SISTEMA ............................................................... 48
6.1 INTERAÇÃO INICIAL COM O USUÁRIO........................................................ 48
6.2 ALGORITMOS ................................................................................................ 50
6.3 COMENTÁRIOS SOBRE O DESENVOLVIMENTO........................................ 55
6.3.1 Codificação dos Caracteres ......................................................................... 55
6.3.2 Limitação de Hardware................................................................................. 56
6.3.3 Levantamento dos Dados............................................................................. 56
6.3.4 Cache nas Páginas WAP ............................................................................. 57
6.3.5 Cronograma do Projeto ................................................................................ 57
7. CONCLUSÃO ................................................................................................... 59
REFERÊNCIAS..................................................................................................... 61
APÊNDICE A: CÓDIGO DA PÁGINA INDEX.JSP............................................... 63
APÊNDICE B: IMPLEMENTAÇÃO DO ALGORITMO DE FLOYD-WARSHALL. 65
APÊNDICE C: IMPLEMENTAÇÃO DO ALGORITMO DE DIJKSTRA................. 69

vii
ÍNDICE DE FIGURAS

Figura 1: Renda familiar por classes do Critério de Classificação Econômica Brasil


............................................................................................................................. 7
Figura 2: Diagrama de Casos de Uso ................................................................... 11
Figura 3: Modelo Entidade Relacionamento.......................................................... 12
Figura 4: Levantamento de Classes...................................................................... 16
Figura 5: Diagrama de Classes ............................................................................. 17
Figura 6: Diagrama de Seqüência do Caso de Uso Atualizar banco de dados..... 18
Figura 7: Diagrama de Seqüência do Caso de Uso Roteirizar .............................. 19
Figura 8: Pseudo-código do Algoritmo de Dijkstra ................................................ 25
Figura 9: Pseudo-código do Algoritmo de Floyd-Warshall .................................... 26
Figura 10: Arquitetura do sistema ......................................................................... 27
Figura 11: Diagrama de Componentes e Implantação .......................................... 28
Figura 12: Código de ligação entre JSP e WML.................................................... 29
Figura 13: Atendimento de requisições HTTP com método GET.......................... 31
Figura 14: Ciclo de vida de um Servlet.................................................................. 31
Figura 15: Código de exibição de dados no formato WML.................................... 32
Figura 16: Fluxo de dados WAP............................................................................ 33
Figura 17: Proxy WAP........................................................................................... 35
Figura 18: Representação do grafo G ................................................................... 37
Figura 19: Algoritmo de Floyd-Warshall modificado .............................................. 38
Figura 20: Matrizes do Algoritmo de Floyd-Warshall............................................. 39
Figura 21: Algoritmo de Dijkstra em execução sobre o grafo G ............................ 40
Figura 22: Vetores do Algoritmo de Dijkstra .......................................................... 41
Figura 23: Gráfico de comparação dos tempos de execução dos algoritmos ....... 44
Figura 24: Gráfico de comparação das distâncias percorridas pelas rotas dos
algoritmos .......................................................................................................... 44
Figura 25: Gráfico de comparação das quadras percorridas pelas rotas dos
algoritmos .......................................................................................................... 45
Figura 26: Página de preenchimento inicial dos dados ......................................... 48

viii
Figura 27: Página informando que os endereços não foram encontrados ............ 49
Figura 28: Página de confirmação dos dados ....................................................... 49
Figura 29: Página com o resultado da roteirização ............................................... 50
Figura 30: Pseudo-código do Algoritmo de Rotas a Pé......................................... 51
Figura 31: Exemplo gráfico de uma rota do Alg. Para Carros ............................... 52
Figura 32: Pseudo-código de parte do Algoritmo Para Ônibus ............................. 54
Figura 33: Cronograma idealizado no pré-projeto (à esquerda) e cronograma
realizado (à direita) ............................................................................................ 58

ix
ÍNDICE DAS TABELAS

Tabela 1: Comparação entre sistemas roteirizadores atuantes no mercado .......... 4


Tabela 2: Entidade Esquinas................................................................................. 13
Tabela 3: Entidade Esquinas_vizinhos_ape.......................................................... 14
Tabela 4: Entidade Esquinas_vizinhos_car........................................................... 14
Tabela 5: Entidade Linha_de_onibus .................................................................... 14
Tabela 6: Entidade Linha_nome............................................................................ 14
Tabela 7: Entidade Ponto_esquinas...................................................................... 14
Tabela 8: Entidade Ponto_nome ........................................................................... 15
Tabela 9: Entidade Pontos_vizinhos ..................................................................... 15
Tabela 10: Entidade Ruas ..................................................................................... 15
Tabela 11: Entidade Quadras................................................................................ 15

x
1

1. INTRODUÇÃO

Conforme as tecnologias evoluem, cresce o acesso e a disponibilidade


dessas à sociedade em geral. Atualmente, a situação da telefonia no Brasil
contrasta profundamente com o que tínhamos há pouco mais de 10 anos. Hoje, é
incomum encontrar alguém que não possua um aparelho celular, sendo
importante observar que os aparelhos mais recentes vêm obrigatoriamente com
um componente chamado mini-browser – o meio de acesso à Internet pelo celular.
Sem maiores estudos, podemos facilmente deduzir que está aí um grande nicho
comercial e tecnológico a ser explorado. É seguindo essas idéias que se enquadra
o projeto proposto.

1.1 TEMA

Atualmente, as grandes empresas multinacionais dominam a rede mundial,


ditando os padrões e formando seguidores em todo o mundo. Entre os muitos
serviços oferecidos por esses grandes portais, está a roteirização. Como chegar a
um determinado endereço? É essa pergunta que tais roteirizadores buscam
responder, através de diversos artifícios, sendo a imagem de um mapa com o
desenho da rota a ser seguida a forma mais comum. Pesquisando na Internet
quais são as empresas que oferecem esse serviço, como é e o que podem fazer
seus produtos, percebe-se que nenhum desses grandes ateve-se ao
desenvolvimento de um mecanismo roteirizador para rotas de ônibus, que possa
informar ao usuário qual(is) ônibus ele deve pegar para chegar ao seu destino, e
ainda, os poucos roteirizadores para dispositivos móveis disponíveis exigem
hardware avançado e bons conhecimentos tecnológicos de seus usuários.
Deve-se lembrar que desenvolver sites para dispositivos móveis não é o
mesmo que desenvolver para computadores pessoais. Há as limitações naturais
desses aparelhos (falta de mouse, navegador primitivo, tela pequena, etc); e
ainda, utilizam-se tecnologias especiais, como a WML, a WMLScript, o WAP, entre
outras. Por essas razões, todos os sistemas roteirizadores existentes e funcionais
2

para navegadores de computadores pessoais tornam-se inválidos quando


acessados pelos atuais navegadores de dispositivos móveis.
O sistema proposto pretende simular um informante fornecendo indicações
sobre o melhor caminho para um destino. A pessoa que está requisitando a
informação deve informar aonde quer chegar, escrevendo o nome da rua onde se
encontra e da rua para onde vai, e indicando se irá fazer o caminho a pé, de carro
ou de ônibus. Feito isso, é exibido o procedimento que deve ser seguido para
alcançar mais apropriadamente o ponto de destino.
Ainda que essa área – roteirização e buscas – seja atualmente dominada
por grandes empresas com muitos funcionários e muitos recursos financeiros,
acreditamos que o diferencial que possuímos é o fato de estarmos fisicamente
ligados à cidade de Curitiba. Dificilmente, por maior que seja, uma empresa
poderá manter atualizada sua base de dados com todas as informações
necessárias para um sistema como o idealizado, para todas as cidades do mundo
ou mesmo do país, como parece ser a intenção dessas organizações.
Definidos o tema e o escopo do projeto, foram levantadas as justificativas
para o desenvolvimento do sistema. Qual a finalidade do trabalho? Que
características o diferenciam de trabalhos semelhantes? O próximo tópico visa
esclarecer essas questões.

1.2 JUSTIFICATIVAS DO PROJETO

Embora muito explorada, a área de roteirização ainda está se


desenvolvendo como produto comercial. Ainda hoje, existem poucas empresas
que oferecem esse serviço, seja para a Internet ou através de softwares. Portanto,
tanto como produto para pessoas, como para empresas (sistema de logística), é
possível inovar e construir um sistema que possa se destacar através do uso das
técnicas de roteirização.
Atualmente, grande parte do público atendido pelos sistemas de
roteirização dispõe de recursos tecnológicos mais avançados, como, por exemplo,
um aparelho celular com capacidade para exibir um mapa. Para atender à parcela
3

alheia a esse tipo de tecnologia, o sistema de roteirização BuscaCuritiba visa


reduzir ao máximo qualquer tipo de dependência a determinado aparelho.
O sistema proposto neste trabalho apresenta um aspecto em relação aos
produtos existentes no mercado que pode ser um diferencial: o algoritmo de
roteirização. Ao contrário dos algoritmos tradicionais utilizados, o algoritmo do
BuscaCuritiba visa minimizar o armazenamento de registros em banco de dados.
Maiores detalhes referentes à comparação entre os algoritmos em relação à
utilização do banco de dados são abordados no capítulo 6.
Na tabela 1, são comparados os 4 principais produtos semelhantes ao
BuscaCuritiba atuantes no mercado. Com base nessa comparação, observa-se
que nenhum dos softwares listados oferece a opção de rotas envolvendo ônibus.
O único produto desenvolvido especificamente para celulares (da empresa
Webraska) exige do aparelho um visor colorido, suporte a GPS e a tecnologia
Java, além de ser restrito a cliente da Nextel.
Dois dos produtos listados são voltados para PDAs (Personal Digital
Assistants) e envolvem custos para sua aquisição. Por fim, o produto da
Mapsolute GmbH consiste em um site web que disponibiliza o cálculo de rotas
gratuitamente.
4

Tabela 1: Comparação entre sistemas roteirizadores atuantes no mercado

Empresa Origem Recursos Produto Custo Site WAP / Ônibus A Carro Curitiba
Necessários Software pé

Webraska França / Java, visor Aplicação Disponível Software N S S S


Brasil colorido e desenvolvida em para clientes
GPS. J2ME (Java 2 Micro da Nextel.
Edition), para
aparelhos com Java e
visor colorido, que
utiliza informações
capturadas do GPS,
o qual se encontra
integrado ao
aparelho.
MapLink Brasil Sistema O MapLink de R$ 399,00 Software N S S S
operacional Destinator é um a R$ 1899,00
Window software para PDA. dependendo
Mobile Não possui versão da versão.
(2003, 4.2 ou para celulares
5.0).
300Mhz de
processador.
64 de
memória
RAM. 256
de memória
de
armazename
nto. GPS
Integrado ou
compatível
com o PDA.
DestinAtor Alemanha Sistema Produto semelhante de R$ 350,00 Software N S S N
Technologies operacional ao software da a R$ 450,00
Window empresa MapLink. dependendo
Mobile 5.0. do
Os aparelhos fornecedor.
que
suportam o
software são
listados no
seguinte
endereço:
www.destina
tortechnologi
es.net/es/pro
ducts/produc
ts/pda/compa
tibility.html
Mapsolute Alemanha Não possui produtos Gratuito Site N S S S
GmbH para dispositivos Tradicional
(Map24) móveis, apenas para
computadores
pessoais.
5

1.3 OBJETIVOS

Entre os objetivos desse projeto, três apresentam maior relevância: a


criação de um site WAP; o desenvolvimento de um algoritmo de roteirização; e a
construção de um sistema eficiente e simples de ser utilizado.

1.3.1 Criação do Site WAP

O desenvolvimento de um sistema ou site que funcione via WAP - para


dispositivos móveis - ainda hoje é um desafio. Devido à limitação das tecnologias
para esse uso, os sistemas dessa categoria são pouco (ou nada) flexíveis, dando
poucas opções ao usuário final e menos opções ainda para o desenvolvedor do
sistema.
O primeiro passo para o desenvolvimento do projeto é a criação de um site
WAP, o qual tem como função a interação com o usuário final. É através desse
site que o sistema é apresentado ao usuário, pedindo as informações necessárias,
informando os eventuais erros, trazendo informações adicionais e informando o
resultado das requisições.
Para a criação desse pequeno sistema WAP, atualmente encontra-se
disponível a rudimentar linguagem WML (Wireless Markup Language), e sua
linguagem complementar, a WMLScript. A WML é semelhante à linguagem HTML,
e a WMLScript, semelhante ao JavaScript, contudo, ambas, com sérias restrições
e muitas incompatibilidades entre os diversos mini-browsers existentes.
Apesar de suas limitações, a WML pode ser utilizada com a maior parte das
linguagens web existentes, como PHP, ASP e JSP. É através de uma dessas
linguagens web que as páginas do site WAP são criadas dinamicamente,
buscando os dados no banco de dados e exibindo-os no formato desejado.

1.3.2 Desenvolvimento de um Algoritmo de Roteirização

“Na teoria de grafos, o problema do caminho mínimo consiste na


6

minimização do custo de travessia de um grafo entre dois nós (ou vértices); custo
este dado pela soma dos pesos de cada aresta percorrida.” [SAMPAIO e
YANASSE]
O desenvolvimento de Algoritmos de Roteirização já é bastante conhecido e
estudado, sendo que existem vários algoritmos famosos, como o Algoritmo de
Dijkstra, o Algoritmo de Bellman-Ford, o Algoritmo A* (lê-se A estrela), o Algoritmo
de Floyd-Warshall, o Algoritmo de Johnson entre outros.
Além da implementação e comparação entre dois desses algoritmos já
conhecidos, uma parte do projeto consiste no desenvolvimento de um ou mais
tipos de algoritmos para calcular os menores ou melhores (conforme o caso)
caminhos entre as esquinas do bairro Centro de Curitiba.
As comparações entre os dois algoritmos selecionados e o novo algoritmo
criado servem para mostrar a eficiência dos mesmos, relacionando parâmetros
como o tempo de execução para o cálculo da rota e a distância percorrida pela
rota calculada.

1.3.3 Sistema eficiente e simples

O sistema tem como público alvo usuários pouco familiarizados com as


novas tecnologias, sendo, portanto, de extrema importância um baixo grau de
dificuldade na sua utilização.
Entre os pontos que influenciam na usabilidade do sistema está a forma
como a resposta final é enviada ao usuário. Como o sistema é destinado a
aparelhos pouco sofisticados, não há a possibilidade da apresentação de imagens
ilustrando a rota gerada, como um mapa, por exemplo.
Sendo assim, a resposta emitida deve indicar as coordenadas geradas de
uma forma bem compreensível e amigável, aproximando-se de uma resposta
humana, para não deixar dúvidas a respeito da rota a ser seguida.
Ainda para uma boa utilização do sistema, diversos detalhes devem ser
analisados, principalmente a forma como o sistema reage aos erros (campos
obrigatórios não preenchidos em formulários, falha na conexão com o banco de
7

dados, etc) que podem surgir.

1.4 REQUISITOS DO SISTEMA

O sistema de roteirização idealizado é destinado, principalmente, para o


público das classes B, C e D, conforme descrito no item 1.3. Supondo como
exemplo de um indivíduo de uma dessas classes alguém que possua um aparelho
celular com acesso à Internet, seja alfabetizado e tenha conhecimentos básicos de
navegação pela WWW.

Figura 1: Renda familiar por classes do Critério de Classificação Econômica Brasil

O sistema visa trazer um auxílio eventual aos usuários, não tendo a


pretensão de ser utilizado diariamente pelos mesmos, como outros softwares
existentes no mercado destinados a grupos específicos, como os taxistas, por
exemplo. Acrescenta-se o fato de que o sistema pretende ser acessível a
aparelhos pouco sofisticados, que não têm grande capacidade de memória ou
processamento. Portanto, explica-se a decisão pela escolha de desenvolver o
sistema para que seja acessado via Internet, opondo-se ao desenvolvimento de
um software que precise ser instalado no celular, exigindo assim uma maior
sofisticação do aparelho utilizado, assim como maiores conhecimentos
tecnológicos do usuário.
O usuário irá acessar o sistema através de seu celular, utilizando um mini-
browser para acessar o servidor onde está instalado o site WAP. Para que esse
8

servidor funcione corretamente, recebendo e respondendo os pedidos, deverá,


basicamente, possuir instalado e configurado os seguintes componentes: banco
de dados PostgreSQL 8.1; container Apache Tomcat 5.5; e a máquina virtual
Java. O Tomcat deve estar configurado para interpretar arquivos com a extensão
wml.
Essa configuração do servidor satisfaz as necessidades da aplicação, a
qual faz uso - além do banco de dados PostgreSQL e das linguagens WML e
WMLScript, já mencionados – da linguagem JSP e de Servlets.
Além da parte técnica, o projeto requer uma série de informações referentes
aos dados utilizados na roteirização: nome das ruas (separadas de quadra em
quadra, com a numeração inicial e final de cada quadra) e sentido do tráfego de
veículos motorizados nas ruas. Considerando como rua todo e qualquer tipo de
logradouro, como avenida, alamedas, etc. E considerando como escopo do projeto
o bairro Centro de Curitiba.
Esses dados encontram-se em guias e sites sobre Curitiba, tendo como
exemplo o guia “Cartoplam 2007-2008”, da editora Cartoplam, que traz todas as
linhas de ônibus da cidade e todas as ruas com suas numerações, além de outras
informações úteis ao sistema. Outra referência de dados é o site
maps.google.com, no qual podem-se encontrar as direções das ruas. Entre outros,
como: curitiba-parana.com, telelistas.net, listaonline.com.br, guia-curitiba.com,
curitibainterativa.com.br, curitiba.pr.gov.br, ippuc.org.br, e urbs-
web.curitiba.pr.gov.br.
Por meio do levantamento de requisitos foram coletadas as informações
necessárias para a definição do foco do trabalho e das funcionalidades oferecidas
pelo sistema. O modo de operação do sistema é descrito no tópico seguinte.

1.5 FUNCIONAMENTO DO SISTEMA

À medida que os requisitos do sistema – anteriormente citados – sejam


obedecidos, o produto estará pronto para ser utilizado.
9

Em suma, inicialmente são solicitadas ao usuário informações referentes às


localidades de origem e destino com as quais se deseja traçar a rota pretendida e
a forma de roteirização (a pé, de carro ou de ônibus). Os dados informados são
utilizados em uma consulta ao banco de dados que retorna os resultados
encontrados. Uma nova página então é exibida com os resultados obtidos no
banco para que seja efetuada uma confirmação.
Os dados confirmados são direcionados para a servlet Java que contém o
algoritmo de cálculo de rotas apropriado para a forma de roteirização selecionada
pelo usuário. Após o cálculo da rota, tem início o algoritmo de formulação da
resposta, que produz uma página com a descrição por extenso da rota a ser
seguida entre as duas localidades fornecidas.
A descrição é impressa na tela finalizando o procedimento, e um link é
acrescido ao fim da descrição para que uma nova roteirização possa ser feita,
iniciando novamente o processo.
10

2. ESPECIFICAÇÃO DO SISTEMA

Um sistema eficiente não depende apenas de um código sem erros ou de


uma boa interface gráfica, mas sim de toda uma estrutura de documentos que
especifique o seu funcionamento e registre o contexto no qual ele foi
desenvolvido.
Mesmo um sistema simples, como o apresentado nesse projeto, deve
utilizar os recursos disponíveis para auxiliar em uma possível continuidade do
projeto, assim como auxiliar durante seu desenvolvimento ou mesmo no seu
funcionamento.
Entre esses recursos, os utilizados foram o diagrama de caso de uso, o
modelo de dados, o modelo entidade relacionamento, o dicionário de dados, o
diagrama de classes e o diagrama de seqüência.

2.1 DIAGRAMA DE CASOS DE USO

O sistema apresenta duas situações que devem ser classificadas como


casos de uso: o momento em que o administrador do sistema atualiza os dados no
banco de dados, supondo que a direção de veículos em alguma rua seja alterada,
por exemplo; e o momento em que o usuário que está utilizando o sistema fornece
os dados para gerar uma rota.
No primeiro caso, o administrador atualiza os dados do sistema, inclui,
exclui e altera os nomes das ruas, números, direções do tráfego de veículo, etc.
No segundo caso, o usuário informa os dados (nome e número dos locais
de origem e destino), submete essas informações e aguarda uma resposta. O
sistema verifica os dados e retorna ao usuário uma página na qual ele deve
confirmar as informações enviadas. Feita a confirmação, o sistema começa a
calcular o caminho entre a origem e destino passados.
A figura a seguir representa, de forma simplificada, as ações esperadas dos
atores (usuário e administrador) e do sistema:
11

Figura 2: Diagrama de Casos de Uso

2.2 MODELO DE DADOS

As informações utilizadas no sistema estão divididas no banco de dados em


uma estrutura de dez tabelas. Cada uma dessas tabelas é descrita no item 2.2.2 e
os relacionamentos entre elas estão descritos no item 2.2.1.

2.2.1 Modelo Entidade Relacionamento

Como representado na figura 3, a seguir, as tabelas relacionam-se,


mantendo a consistência dos dados no banco. As coordenadas das esquinas são
guardadas na tabela ‘Esquinas’, com um identificador único para cada esquina do
Centro de Curitiba e suas coordenadas x e y. A ‘Esquinas’ relaciona-se
diretamente com outras quatro tabelas.
12

Figura 3: Modelo Entidade Relacionamento

Através de seu relacionamento com a ‘Esquinas_vizinho_ape’, pode-se


saber quais as esquinas adjacentes da esquina passada. O mesmo ocorre para a
‘Esquina_vizinho_car’, com a diferença que a informação obtida é para saber para
13

quais esquinas adjacentes o tráfego de veículos é permitido.


Cada quadra de cada rua é guardada com sua numeração inicial e final na
‘Quadras’, que é relacionada, além da ‘Esquinas’, com a ‘Ruas’, onde se
encontram os nomes de todas as ruas cadastradas.
Os pontos de ônibus são relacionados com as esquinas através do
relacionamento entre a ‘Esquinas’ e a ‘Ponto_esquinas’. Esta última utiliza uma
relação com a ‘Ponto_nome’, onde são descritos todos os pontos de ônibus.
‘Ponto_nome’ também mantém um relacionamento com a ‘Ponto_vizinhos’, para
informar quais são os vizinhos desse ponto, ou seja, qual o próximo ponto que o
ônibus poderá parar.
Finalizando os relacionamentos, tem-se a ‘Linha_de_onibus’, que informa
quais os pontos de ônibus que formam uma determinada linha, descritas pela
relação com a ‘Ponto_nome’. As linhas são descritas na ‘Linha_nome’.

2.2.2 Dicionário de Dados

Conforme o item anterior mostrou, existe um total de dez tabelas na


estrutura do banco de dados utilizado, e essas tabelas utilizam relacionamentos
entre elas para manter a consistência dos dados.
Nesse item são descritos os tipos de cada tabela, ou seja, quais campos e
quais os formatos desses campos que compõem cada uma dessas entidades.
A entidade Esquinas contém os identificadores para cada esquina e suas
respectivas coordenadas x e y.

Tabela 2: Entidade Esquinas


esquinas
campo tipo tamanho formato descrição
id_esquina int 8 [0-9] identificador da esquina
x int 8 [0-9] coordenada x da esquina
y int 8 [0-9] coordenada y da esquina

A entidade Esquinas_vizinhos_ape informa quais são as esquinas vizinhas


de uma determinada esquina, desconsiderando o sentido das vias.
14

Tabela 3: Entidade Esquinas_vizinhos_ape


esquinas_vizinhos_ape
campo tipo tamanho formato descrição
id_esquina int 8 [0-9] identificador da esquina
viz int 8 [0-9] identificador da esquina vizinha

A entidade Esquinas_vizinhos_car informa quais são as esquinas vizinhas


de uma determinada esquina, considerando o sentido das vias.

Tabela 4: Entidade Esquinas_vizinhos_car


esquinas_vizinhos_car
campo tipo tamanho formato descrição
id_esquina int 8 [0-9] identificador da esquina
viz int 8 [0-9] identificador da esquina vizinha

A entidade Linha_de_onibus contém todos os pontos de ônibus associados


a uma determinada linha de ônibus.

Tabela 5: Entidade Linha_de_onibus


linha_de_onibus
campo tipo tamanho formato descrição
id_linha int 8 [0-9] identificador da linha de ônibus
id_ponto int 8 [0-9] identificador do ponto de ônibus

A entidade Linha_nome contém uma lista com os nomes das linhas de


ônibus da cidade.

Tabela 6: Entidade Linha_nome


linha_nome
campo tipo tamanho formato descrição
id_linha int 8 [0-9] identificador da linha de ônibus
nome_linha varchar 255 [A-Z] nome da linha de ônibus

A entidade Ponto_esquinas faz uma relação entre cada ponto de ônibus e a


sua esquina mais próxima.

Tabela 7: Entidade Ponto_esquinas


ponto_esquinas
campo tipo tamanho formato descrição
id_ponto int 8 [0-9] identificador do ponto de ônibus
id_esquina int 8 [0-9] identificador da esquina

A entidade Ponto_nome contém uma lista com os nomes dos pontos


relacionados com seus identificadores.
15

Tabela 8: Entidade Ponto_nome


ponto_nome
campo tipo tamanho formato descrição
id_ponto int 8 [0-9] identificador do ponto de ônibus
nome_ponto varchar 255 [A-Z] nome do ponto de ônibus

A entidade Pontos_vizinhos informa quais são os pontos de ônibus


alcançáveis a partir de um determinado ponto de ônibus.

Tabela 9: Entidade Pontos_vizinhos


pontos_vizinhos
campo tipo tamanho formato descrição
id_ponto int 8 [0-9] identificador do ponto de ônibus
viz_ponto int 8 [0-9] identificador do ponto de ônibus
vizinho

A entidade Ruas contém o nome de todas as ruas.

Tabela 10: Entidade Ruas


ruas
campo tipo tamanho formato descrição
id_rua int 8 [0-9] identificador da rua
nome_rua varchar 255 [A-Z] nome da rua

A entidade Quadras contém todas as quadras de todas as ruas, informando


qual a numeração que a limita, o identificador das duas esquinas que a compõem
e o nome da rua a qual a quadra pertence.

Tabela 11: Entidade Quadras


quadras
campo tipo tamanho formato descrição
viz1 int 8 [0-9] identificador da esquina 1
viz2 int 8 [0-9] identificador da esquina 2
id_rua int 8 [0-9] id da rua compreendida entre as
esquinas 1 e 2
num_viz1 int 8 [0-9] numeração da rua na esquina 1
num_viz2 int 8 [0-9] numeração da rua na esquina 2

2.3 LEVANTAMENTO DE CLASSES

Foram levantadas um total de cinco classes para o desenvolvimento do


sistema: DesenhaFormulario, AtualizaBD, FormulaString, Roteiriza e AcessaBD.
A classe DesenhaFormulario tem como finalidade a apresentação das telas
16

de formulário para o usuário, solicitando e analisando os dados para que a


roteirização possa ser efetuada.
AtualizaBD e AcessaBD são as classes responsáveis pela interface do
sistema com o banco de dados, é através delas que a conexão será iniciada e os
dados serão buscados ou atualizados.
O algoritmo de roteirização se encontra na classe Roteiriza, a qual recebe
os dados da DesenhaFormulário, gera a rota e devolve o resultado novamente
para a DesenhaFormulario.
Como os dados são convertidos para uma linguagem mais amigável, uma
classe é responsável por essa conversão: a FormulaString. Essa classe é usada
pela Roteiriza, após ter encontrado todas as coordenadas do percurso.
A figura 4 representa o Levantamento de Classes:

Figura 4: Levantamento de Classes

2.4 DIAGRAMA DE CLASSES

Como mencionado no item anterior, cinco classes são responsáveis pelo


funcionamento do sistema. A ligação dessas classes pode ser representada
17

através da figura 5.
A classe Roteiriza é o núcleo do sistema, sendo a responsável direta pelos
cálculos que resultam na rota desejada. Como será mostrado no próximo item,
todo o processo começa quando a DesenhaFormulario recebe os dados e faz uma
chamada aos métodos da Roteiriza. Nesse momento as demais classes são
utilizadas, seja para acessar o banco de dados ou para formatar a resposta
enviada para o usuário.

Figura 5: Diagrama de Classes

2.5 DIAGRAMA DE SEQÜÊNCIA

O fluxo de ações dos dois casos de usos descritos no item 2.1 pode ser
representado através dos diagramas de seqüência das figuras 6 e 7, a seguir. No
primeiro caso de uso, no qual o administrador do sistema gerencia os dados
armazenados no banco de dados, a classe AtualizaBD (descrita no item 2.3) é
utilizada para incluir, excluir ou alterar as informações, conforme as necessidades
do administrador.
18

Figura 6: Diagrama de Seqüência do Caso de Uso Atualizar banco de dados

No caso de uso em que o usuário busca uma rota, as demais classes são
utilizadas. Primeiramente, a classe DesenhaFormulario desenha a tela inicial e
aguarda o usuário inserir os dados. Feita essa inserção, os dados são enviados
para a Roteiriza analisar. Se um erro ocorrer, por exemplo, algum campo
obrigatório do formulário permaneceu em branco, a DesenhaFormulario recebe
uma notificação do erro. Senão, a AcessaBD é utilizada para buscar os dados no
banco e retornar o que encontrou. O retorno é enviado para a Roteiriza, que trata
esses dados e envia para a DesenhaFormulario mostrar ao usuário o que foi
encontrado. Assim que o usuário confirma as informações, a DesenhaFormulario
novamente envia os dados para a Roteiriza, que novamente utiliza a AcessaBD,
mas agora para obter o caminho entre o destino e origem passados e confirmados
pelo usuário. Após ter encontrado esse caminho, a Roteiriza usa a FormulaString
para formatar os dados em um formato compreensível pelo usuário, e, então,
retorna essas indicações geográficas para a DesenhaFormulario mostrar ao
usuário.
19

Figura 7: Diagrama de Seqüência do Caso de Uso Roteirizar


20

3. TECNOLOGIAS E ALGORITMOS

Neste item está uma descrição sucinta de cada uma das tecnologias,
softwares e algoritmos utilizados durante o desenvolvimento do projeto. Outras
informações podem ser encontradas nas fontes originais, indicadas nas
referências bibliográficas.
No item ‘Ferramentas de Desenvolvimento’ as tecnologias aqui descritas
são contextualizadas no projeto, mostrando quais as suas funções e onde se
encaixam na arquitetura do sistema desenvolvido.

3.1 JSP E SERVLETS

JSP (Java Server Pages) é uma tecnologia voltada para o desenvolvimento


de aplicações web e possui como principal característica a sua portabilidade a
diversas plataformas. Assim como outras linguagens de programação para web,
JSP fornece ao desenvolvedor funcionalidades como acesso a banco de dados e
tratamento de requisições do usuário.
Como característica, o JSP oferece a vantagem de ser facilmente
codificado, auxiliando na manutenção do código. Além disso, separa as interfaces
de usuário da geração de conteúdo, permitindo o trabalho conjunto entre
programadores e designers. (TELEMACO, 2004).
Enquanto o JSP se encarrega de fornecer maior interatividade ao usuário,
as Servlets operam no lado do servidor respondendo a requisições enviadas por
clientes, muitas vezes sem se preocupar com o conteúdo a ser exibido.
As Servlets permitem ao desenvolvedor trabalhar com as mesmas
funcionalidades oferecidas pela linguagem de programação Java, com a vantagem
adicional de tratar requisições de cliente e responder em formato HTML, que pode
ser interpretado por navegadores web.
No desenvolvimento de aplicações web, muitas vezes as Servlets operam
em conjunto com o JSP. A utilização conjunta das duas tecnologias auxilia na
21

separação entre a lógica da programação e o conteúdo e layout de páginas web.


(JEVEAUX, 2004).

3.2 TOMCAT

O Tomcat é um servidor de aplicações Java para web. É distribuído como


software livre e desenvolvido como código aberto dentro do conceituado projeto
Apache Jakarta e oficialmente endossado pela Sun como a Implementação de
Referência (RI) para as tecnologias Java Servlet e Java Server Pages (JSP). O
Tomcat é robusto e eficiente o suficiente para ser utilizado mesmo em um
ambiente de produção.
Tecnicamente o Tomcat é um container web, cobrindo parte da
especificação J2EE com tecnologias como Servlet e JSP, e tecnologias de apoio
relacionadas como Realms e segurança, JNDI Resources e JDBC DataSources. O
Tomcat tem a capacidade de atuar também como servidor web/HTTP, ou pode
funcionar integrado a um servidor web dedicado como o Apache httpd ou o
Microsoft IIS.
Como um container, o Tomcat tem entre suas funções “criar os objetos de
solicitação e resposta, criar ou alocar uma nova thread para o servlet, passando
as referências de solicitação e resposta como argumentos. É o container que
entrega ao servlet a solicitação e a resposta HTTP” (BASHAM, 2005).

3.3 POSTGRESQL E PGADMIN

O PostgreSQL consiste em um SGBD (Sistema Gerenciador de Banco de


Dados) objeto-relacional de código aberto derivado do projeto POSTGRES da
Universidade de Berkeley. Ele recebe a classificação de objeto-relacional por
apresentar algumas características de orientação a objetos, como heranças e
tipos personalizados (BIAZUS, 2003).
22

A versão atual do PostgreSQL é a 8.2, lançada recentemente. A versão


utilizada na elaboração do projeto foi a 8.1, por ser a mais estável e atualizada
encontrada no início do desenvolvimento do trabalho.
O PGAdmin é uma ferramenta software livre com o código disponível para
download. Ela oferece suporte multiplataforma (MS Windows 2000 e XP,
GNU/Linux e FreeBSD). Oferece suporte às versões mais recentes do
PostgreSQL, possui acesso a todos os objetos PostgreSQL, além de acesso
nativo PostgreSQL. É considerada uma ferramenta limitada, pois o PGAdmin não
permite filtros, não se pode alterar os dados no mesmo lugar em que eles são
exibidos, e abre muitas janelas desnecessariamente.
Essa ferramenta não oferece geração de diagramas e também não gera
scripts de backup. Outra parte fraca dessa ferramenta é a exportação de dados. O
site oficial do PGAdmin é o www.pgadmin.org, onde muitas informações podem
ser encontradas a seu respeito e onde pode ser feito o seu download.

3.4 WAP

O WAP (Wireless Application Protocol) é um padrão internacional para


aplicações que utilizam comunicações sem fio, como, por exemplo, acesso à
Internet a partir de um telefone celular. Foi desenvolvido para prover serviços
equivalentes a um navegador web com alguns recursos específicos para serviços
móveis (W3SCHOOLS, 2007).
Sua arquitetura é dividida em camadas, assim como a arquitetura TCP/IP:

1. WAE (Ambiente de Aplicativos). Esta é a camada mais alta da arquitetura


WAP. É nela que está a maior preocupação dos desenvolvedores, pois é
aqui que estão estabelecidos os padrões das linguagens WML, WMLScript
e dos browsers.
2. WSP (Protocolo de Sessão sem Fio). É a versão binária do protocolo HTTP
1.1. Criada somente para garantir transações em largura de banda
pequena, porém com uma grande diferença, pode-se parar ou reiniciar uma
conexão.
23

3. WTP (Protocolo de Transação sem Fio). Um protocolo ágil que suporta


requisições unidirecionais não confiáveis, requisições unidirecionais
confiáveis e transações do tipo requisição/resposta.
4. WTLS (Segurança na Camada de Transporte sem Fio). Esta camada é
baseada no padrão TLS hoje conhecido com SSL (Security Socker Layer).
Ela proporciona integridade e privacidade de dados, autenticação e
proteção de serviços, além de recusa de serviços. Pode ativar o WTLS da
mesma forma com que se ativa o HTTPS nos servidores web.
5. WDP (Protocolo de datagramas sem fio). É esta a camada que proporciona
a consistência entre as várias operadoras sem fio com a primeira camada
de aplicativo. Abaixo desta camada que estão as várias redes utilizadas
pelas operadoras.

3.5 WML E WMLSCRIPT

A WML (Wireless Markup Language) é uma linguagem de marcação


utilizada em aparelhos que implementam a especificação do WAP (Wireless
Application Protocol), como telefones celulares. A grande vantagem dessa
tecnologia em detrimento de outras linguagens de marcação é a baixa exigência
de poder de processamento, fator crucial para o desenvolvimento de aplicações
voltadas para aparelhos celulares.
Sua estrutura é muito semelhante à da HTML (HyperText Markup
Language), utilizada no desenvolvimento de páginas web, pois proporciona
suporte à navegação, hyperlinks, apresentação de imagens e formulários. Porém,
a WML possui uma estruturação peculiar composta por cartões, em que cada
cartão representa uma interação com o usuário. (W3SCHOOLS, 2007).
A WMLScript (Wireless Markup Language Script) é uma linguagem para a
criação de scripts orientada a objetos, que tem como finalidade melhorar os
recursos limitados da WML. (FORTA, 2000). Projetada pela WAP Fórum como
uma linguagem procedural enxuta, com estrutura semelhante a linguagens C++ e
Java, porém menos resistente.
24

A WMLScript foi implementada para executar do lado do cliente pelo fato da


banda de dados ser limitada. É uma linguagem fracamente tipada, ou seja, seu
tipo pode ser alterado durante o seu ciclo de vida. Utilizada para criar cálculos
básicos, validar entrada de usuário, interação com aplicativos internos e externos
ao navegador, processamento local de informações, etc.

3.6 NOKIA MOBILE INTERNET TOOLKIT (NMIT)

Toda linguagem de marcação demanda um ambiente de desenvolvimento e


com a WML não poderia ser diferente. Para o desenvolvimento e testes com
páginas WAP, o Nokia Mobile Internet Toolkit (NMIT) demonstra-se uma
ferramenta eficiente. O NMIT é uma ferramenta que suporta a criação de
componentes para a Internet móvel, contendo tecnologias como o XHTML, o WAP
e o MMS. As aplicações podem ser visualizadas nas SDKs suportadas.
A criação de diferentes conteúdos para dispositivos móveis no NMIT é
facilitada através de um conjunto de editores e wizards. Isto inclui a criação de
páginas web (editor para WML, XHTML e CSS), criação de MMS (editores para a
criação de MMS com mensagens SMIL) e criação de mensagens Push (editores
para a criação multipart e mensagens Service Indication/Service Loading).
(NOKIA, 2004).
Além de servir como ambiente de desenvolvimento, o NMIT é um emulador
WAP. “Emuladores WAP são dispositivos que emulam no computador pessoal
telefones para testar o código sem ser preciso usar um dispositivo real. Eles
permitem navegar em arquivos locais sem precisar de um gateway ou servidor
WAP” (FORTA, 2000).

3.7 ALGORITMO DE DIJKSTRA

O algoritmo de Dijkstra é o mais famoso dos algoritmos para cálculo de


caminho de custo mínimo entre vértices de um grafo e, na prática, o mais
empregado.
25

Escolhido um vértice como raiz da busca, este algoritmo calcula o custo


mínimo deste vértice para todos os demais vértices do grafo. O algoritmo pode ser
usado sobre grafos orientados (dígrafos), ou não, e admite que todas as arestas
possuam pesos não negativos (nulo é possível). Esta restrição é perfeitamente
possível no contexto de redes de transportes, onde as arestas representam
normalmente distâncias ou tempos médios de percurso; poderão existir, no
entanto, aplicações onde as arestas apresentem pesos negativos, nestes casos o
algoritmo não funcionará corretamente. (NONATO, 2004).

// 1º passo: iniciam-se os valores:


para todo v V[G]
d[v]← ∞
π[v] ← nulo
d[s] ← 0

/* V[G] é o conjunto de vértices(v) que formam o Grafo G. d[v] é o vetor de distâncias de s até cada v. Admitindo-se a
pior estimativa possível, o caminho infinito. π[v] identifica o vértice de onde se origina uma conexão até v de maneira a
formar um caminho mínimo.*/
// 2º passo: temos que usar dois conjuntos: S, que representa todos os vértices v onde d[v] já contém o custo do menor
caminho e Q que contém todos os outros vértices.
//3º passo: realizamos uma série de relaxamentos das arestas, de acordo com o código:

enquanto Q ≠ ø
u ← extraia-mín(Q)
S ← S {u}
para cada v adjacente a u
se d[v] > d[u] + w(u, v) //relaxe (u, v)
então d[v] ← d[u] + w(u, v)
π[v] ← u

/* w(u, v) é o peso(weight) da aresta que vai de u a v. u e v são vértices quaisquer e s é o vértice inicial.
extraia-mín(Q), pode ser um heap de mínimo ou uma lista ordenada de vértices onde obtém-se o menor elemento, ou
qualquer estrutura do tipo.*/

Figura 8: Pseudo-código do Algoritmo de Dijkstra

3.8 ALGORITMO DE FLOYD-WARSHALL

Ao contrário de Dijkstra, o algoritmo de Floyd-Warshall calcula o custo


mínimo entre todos os vértices de um determinado grafo, o que acarreta em maior
armazenamento de dados, seja em banco de dados ou memória.
Na ciência da computação, o algoritmo de Floyd-Warshall (às vezes
chamado de algoritmo de Roy-Floyd ou algoritmo de Warshall) é um algoritmo que
resolve o problema de calcular o caminho mais curto entre todos os pares de
26

vértices em um grafo orientado (com direção) e valorado (com peso). Sua


complexidade é cúbica.
Dentre outras aplicações, o algoritmo de Floyd-Warshall é utilizado em
inversões de matrizes de números reais, na busca de uma expressão regular pela
denotação de uma linguagem regular aceita por um autômato finito e na
otimização do roteamento.

Figura 9: Pseudo-código do Algoritmo de Floyd-Warshall


27

4. FERRAMENTAS DE DESENVOLVIMENTO

As ferramentas (softwares e tecnologias) descritas no item anterior formam


um conjunto interligado que é a base do funcionamento do sistema de roteirização
desenvolvido. Este item mostra como esse conjunto está interligado e em que
momento do projeto cada tecnologia foi aplicada.

4.1 ARQUITETURA DO SISTEMA

A figura 10 é uma representação básica da ligação entre as tecnologias


utilizadas, onde pode-se perceber que o código - JSP e Servlets - é ligado
diretamente ao servidor Tomcat, sem o qual perderia sua funcionalidade.
Utilizado apenas durante a fase de desenvolvimento, e não mais em
produção, o PGAdmin é um cliente que conecta-se diretamente ao banco de
dados PostgreSQL, o qual liga-se ao JSP e às servlets Java para responder
requisições de consultas e inserções de dados.
As tecnologias wireless formam outro bloco, interligando a linguagem WML
às outras da codificação através do protocolo WAP. O NMIT (emulador) faz o
papel de usuário final, conectando-se ao WAP para ter acesso a todo o conjunto.

Figura 10: Arquitetura do sistema


28

Figura 11: Diagrama de Componentes e Implantação

A Figura 11 representa, superficialmente, em quais partes dessa arquitetura


as principais classes do sistema são utilizadas.

4.2 WML E JSP

A linguagem WML foi utilizada juntamente com as JSPs para mostrar o


sistema para o usuário, sendo essas as tecnologias responsáveis pela formação
das páginas do site WAP.
Dois arquivos .jsp foram criados para a implementação básica do sistema:
index.jsp e confirma.jsp. Embora sejam arquivos com a terminação .jsp, esses
arquivos são lidos pelo navegador como arquivos .wml e, portanto, não serão
interpretados por um navegador de desktop.
Para criar essa ligação entre JSP e WML, os arquivos implementaram a
estrutura descrita na Figura 12.
29

1) <%@ page import="java.io.*,java.util.*" %>


2) <% response.setContentType("text/vnd.wap.wml"); %>
3) <% response.setCharacterEncoding("ISO-8859-1"); %>
4) <% response.setHeader("Cache-Control","no-cache"); %>
5) <?xml version="1.0" encoding="ISO-8859-1"?>
6) <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
7) <wml>
8) //código
9) </wml>

Figura 12: Código de ligação entre JSP e WML

A quinta linha do documento é uma declaração XML e deve sempre ser


incluída, pois define a versão XML do documento. Neste caso estamos
especificando a versão 1.0 da XML. A sexta linha indica o documento de definição
de tipos e o endereço do consórcio mantenedor da WML.
Na seqüência, o documento possui o elemento <wml> que contém todos os
outros subelementos e entidades usadas no documento e termina com </wml>.
Assim como HTML as tags são envolvidas por <> e </>. A WML não trabalha com
o conceito de página, ela utiliza novos conceitos: deck (baralho) e cards (cartas).
Desta forma, as telas que compõem uma aplicação WML são definidas como um
conjunto de uma ou mais cards.
O deck é o próprio documento WML, e por isso não precisa ser declarado.
Cada deck pode conter vários cards. Cada card precisa ser declarado usando um
par de tags, <cards> e </cards>, indicando o ínicio e fim de um card. Uma
observação importante é que, assim como XML, a WML é case-sensitive, e
diferencia entre caracteres maiúsculos e minúsculos. Assim: carta1, Carta1 e
cArta1 são considerados diferentes.
Resumindo, a WML oferece suporte a seis áreas principais (FORTA, 2000):
1 - Layout e apresentação de texto: embora a saída do código WML
produzido varia entre os dispositivos e navegadores WML específicos;
30

2 - Imagens: ainda que os dispositivos compatíveis com WAP não precisem


oferecer suporte a imagens, a WML suporta o formato de imagem Wireless Bitmap
(WBMP) e o alinhamento de imagens na tela. O formato gráfico Wireless Bitmap é
um formato gráfico criado pela WAP Fórum otimizado para os dispositivos móveis.
3 - Entrada do usuário: a WML oferece suporte a listas de opções, listas de
opções com vários níveis, entrada de texto e controles de tarefa.
4 - Organização dos cartões e decks: as interações com o usuário dividem-
se em cartões e a navegação ocorre entre eles. Na HTML ver uma página é o
mesmo que ver um cartão na WML. Mas, em vez de cada página HTML
representar um arquivo HTML, vários cartões WML representam um deck WML,
que é salvo como um único arquivo.
5 - Navegação: o WAP oferece suporte aos links ancorados e ao esquema
de nomenclatura de URLs da Internet padrão, permitindo a navegação entre
cartões em um deck, entre decks ou entre outros recursos na rede.
6 - Gerenciamento de estado e de contexto: para maximizar os recursos da
rede, o WAP permite que variáveis sejam transmitidas entre arquivos WML. Em
vez de enviar uma seqüência completa, as variáveis podem ser enviadas e
substituídas no tempo de execução. O agente usuário pode armazenar em cache
variáveis e arquivos WML, minimizando ocorrência de cache e solicitações do
servidor. Também é possível passar variáveis em cartões diferentes no mesmo
deck; essa é uma maneira importante de minimizar a utilização da rede.

4.3 SERVLET

Foram criadas três servlets para receber os dados passados pelo usuário e
gerar a rota, cada uma responsável por um determinado tipo de roteirização. Após
inicializadas no servidor Tomcat, as servlets respondem às requisições dos
clientes com o texto informativo da rota a ser percorrida. Cada servlet é dividida
em dois algoritmos: um para descobrir o melhor caminho entre os pontos
passados e o outro para criar a resposta apresentada para o usuário.
A geração da resposta segue o mesmo padrão da geração de saída HTML
31

simples típica das servlets Java, salvo algumas adaptações para abrigar o
conteúdo formatado nas regras da linguagem WML. Para enviar uma resposta ao
cliente, é inserida no código uma chamada ao método getWriter do objeto da
classe HttpServletResponse, que retorna uma referência a um objeto da classe
PrintWriter. Essa classe é a responsável pelo encapsulamento de streams
utilizados para a transmissão de dados do tipo texto e, por essa razão, deve ser
utilizada para enviar informações ao requisitante.
Abaixo um exemplo ilustrativo da explicação do parágrafo anterior.

public void doGet(HttpServletReques request, HttpServletRespons response)


throws IOException {
PrintWriter out = response.getWriter();
out.print( “<HTML><BODY>” );
out.print( “Hello World!” );
out.println( “</BODY>< /HTML>” );
}

Figura 13: Atendimento de requisições HTTP com método GET

Toda servlet segue um ciclo de vida composto de 3 fases: inicialização,


atendimento de requisições e finalização. A inicialização ocorre quando o Servlet
Container carrega a servlet. A partir desse momento, a servlet passa a atender
requisições enquanto o servidor estiver ativo e a aplicação que a contém estiver
carregada. Finalmente, quando o servidor é finalizado ou a aplicação é tornada
inativa pelo Servlet Container, a servlet é finalizada. (TEMPLE, 2004)

Figura 14: Ciclo de vida de um Servlet


32

Conforme mencionado anteriormente, houve a necessidade de adaptar o


conteúdo da resposta para o formato da linguagem WML. Para isso, inseriu-se no
código uma chamada ao método setContentType da classe HttpServletResponse,
que exige a especificação de um tipo de conteúdo como parâmetro. Definido o
formato do conteúdo, a transmissão da página WAP para o cliente foi realizada
com a utilização dos mesmos métodos necessários para a transmissão de uma
página HTML. As únicas informações alteradas foram os parâmetros desses
métodos, que contêm as tags específicas da linguagem WML.
O exemplo abaixo ilustra a adaptação descrita no parágrafo anterior.

response.setContentType("text/vnd.wap.wml");
out.println("<?xml version='1.0'?><!DOCTYPE wml PUBLIC '-
//WAPFORUM//DTD WML 1.1//EN'
'http://www.wapforum.org/DTD/wml_1.1.xml'>");
out.println("<wml>”);
//código
out.println(“</wml>”);

Figura 15: Código de exibição de dados no formato WML

4.4 WAP

A pilha de protocolos WAP é utilizada durante todo o processo de obtenção


de dados, ou seja, é utilizada durante a transmissão dos dados entre o servidor
web e o dispositivo móvel. A figura 16 mostra de forma simplificada como é o
fluxo dos dados entre um celular e o servidor contendo a aplicação:
33

Figura 16: Fluxo de dados WAP

O celular que está acessando o sistema primeiramente se conecta,


utilizando o protocolo WAP, ao Gateway WAP de sua operadora, e então esse
Gateway repassa a requisição, utilizando o protocolo HTTP, ao servidor web que
contém a aplicação.
Desenvolvido pelo WAP Fórum, união das maiores empresas de
comunicação – Ericsson, Nokia, Phone.com, entre outras -, o WAP surgiu em
junho de 1997, quando as empresas buscavam aplicações avançadas para a
Internet. Foi criado exclusivamente para dispositivos sem fio, tais como telefones
celulares, pagers e PDAs, tendo como objetivo unir um servidor de aplicação a
esses dispositivos wireless (ARAÚJO, 2001).
Dispositivos portáteis wireless possuem recursos de computação mais
restritos se comparados a computadores desktop:

· CPU's menos poderosas;


· Menos memória (RAM e ROM);
· Consumo de potência restrito;
· Visores menores;
· Dispositivos de entradas diferentes (pequeno conjunto de teclas, etc).
34

Similarmente, redes móveis de dados apresentam um ambiente mais hostil


de comunicação se comparado ao de redes com fios. Devido a limitações de
potência, disponibilidade de espectro e mobilidade, rede de dados wireless
tendem a possuir:

· Menos banda passante;


· Maior latência;
· Menos estabilidade na conexão;
· Menos disponibilidade.

Como conseqüência, a comunicação wireless fica prejudicada. A


especificação WAP deve, portanto, adequar seus protocolos a fim de minimizar as
diferenças entre estes dois ambientes e prover serviços wireless da melhor forma
possível.
O WAP utiliza a tecnologia Proxy para conexão entre o domínio wireless e a
WWW. O Proxy WAP é composto das seguintes funcionalidades:

· Gateway de Protocolos, que traduz "requests" provenientes da pilha de


protocolos WAP para a pilha de protocolos WWW (HTTP e TCP/IP);
· Codificadores e Decodificadores de Conteúdos. Codificadores de
conteúdo codificam o conteúdo WAP (informação WML) em uma forma compacta
a fim de reduzir o volume de dados a ser transmitido na rede wireless.
Decodificadores fazem o inverso.
35

Figura 17: Proxy WAP

O Proxy WAP permite que conteúdo e aplicações possam se hospedar em


servidores WWW convencionais, beneficiando-se de toda tecnologia de Internet
existente. O Proxy WAP utiliza o protocolo HTTP 1.1 para comunicação com o
servidor WWW.
36

5. ANÁLISE DOS ALGORITMOS

Para analisar a eficiência do algoritmo BuscaCuritiba, este capítulo o


compara a dois outros algoritmos também empregados em problemas de cálculo
de caminhos de custo mínimo: o Dijkstra e o Floyd-Warshall. Ambos já foram
apresentados no capítulo 3 (itens 3.7 e 3.8 respectivamente), porém neste tópico
os abordaremos mais profundamente com a utilização de um grafo para
exemplificar seu funcionamento.
O algoritmo BuscaCuritiba demonstra algumas semelhanças em relação
aos algoritmos de Dijkstra e Floyd-Warshall e, por essa razão, esses foram os
selecionados para a comparação. Os três algoritmos visam solucionar o problema
do cálculo de uma rota com a menor distância entre dois pontos. Para isso,
utilizam-se de um grafo (um mapa, por exemplo) composto por vértices (esquinas,
pontos de ônibus, etc).
Evidentemente, apesar de algumas semelhanças, os algoritmos
apresentam também diferenças. Em relação à distância entre vértices, os
algoritmos de Dijkstra e Floyd-Warshall trabalham com arestas (valores que
indicam o custo para percorrer um certo caminho entre dois vértices), já o
BuscaCuritiba utiliza distâncias calculadas entre dois pontos de um plano
cartesiano.
Como será explicado posteriormente, para poder comparar os três
algoritmos foram necessárias adaptações aos dois algoritmos selecionados.

5.1 EXEMPLO DE GERAÇÃO DE BANCO E CÁLCULO DE ROTEIRIZAÇÃO

Supondo o grafo G com o conjunto de vértices V = {1, 2, 3, 4, 5} e com o


conjunto de arestas E = {{1,2}, {1,4}, {2,3}, {2,5}, {3,5}, {4,1}, {4,2}, {4,5}, {5,4}},
conforme a figura 18, vamos analisar o comportamento de cada um dos três
algoritmos apresentado durante as fases de geração do banco e de obtenção de
uma rota.
37

Figura 18: Representação do grafo G

5.1.1 Geração do banco de dados e roteirização: Floyd-Warshall

O Algoritmo de Floyd-Warshall utilizará as informações do grafo referentes


às distâncias entre os vértices para criar uma matriz n X n, sendo n igual a 5, pois
o grafo G possui 5 vértices. Nessa primeira matriz gerada – matriz infinito -, cada
linha representa um vértice de origem e cada coluna um vértice de destino. Para
os vértices que não possuem ligação é incluído um valor muito alto, representando
o infinito e o valor zero é colocado nas ligações onde origem e destino são o
mesmo vértice.
Utilizando somente a matriz infinito o Algoritmo de Floyd-Warshall trará
como resultado qual a menor distância entre dois pontos quaisquer do grafo,
contudo, essa informação não é suficiente para uma rota ser gerada, pois é
necessário saber quais vértices foram utilizados para obter essa distância mínima
informada. Para tanto, há uma pequena modificação que deve ser feita no
algoritmo original para obtermos os caminhos desejados. A figura 19 mostra o
algoritmo modificado.
38

Figura 19: Algoritmo de Floyd-Warshall modificado

Após utilizar o algoritmo modificado, obtém-se duas matrizes: uma


indicando as menores distâncias entre dois pontos quaisquer e outra indicando o
caminho que deve ser utilizado para se obter essas menores distâncias. A figura
20 mostra o estado das duas matrizes conforme as iterações ocorrem até se
encontrar o menor caminho entre todos os pontos do grafo.

Matriz com as menores distâncias Matriz com os caminhos mínimos


1 2 3 4 5 1 2 3 4 5
1 0 1 9999 5 9999 1 0 0 0 0 0
2 9999 0 1 9999 1 2 0 0 0 0 0
3 9999 9999 0 9999 5 3 0 0 0 0 0
4 1 2 9999 0 1 4 0 1 0 0 0
5 9999 9999 9999 1 0 5 0 0 0 0 0

1 2 3 4 5 1 2 3 4 5
1 0 1 2 5 2 1 0 0 2 0 2
2 9999 0 1 9999 1 2 0 0 0 0 0
3 9999 9999 0 9999 5 3 0 0 0 0 0
39

4 1 2 3 0 1 4 0 1 1 0 0
5 9999 9999 9999 1 0 5 0 0 0 0 0

1 2 3 4 5 1 2 3 4 5
1 0 1 2 5 2 1 0 0 2 0 2
2 9999 0 1 9999 1 2 0 0 0 0 0
3 9999 9999 0 9999 5 3 0 0 0 0 0
4 1 2 3 0 1 4 0 1 1 0 0
5 9999 9999 9999 1 0 5 0 0 0 0 0

1 2 3 4 5 1 2 3 4 5
1 0 1 2 5 2 1 0 0 2 0 2
2 9999 0 1 9999 1 2 0 0 0 0 0
3 9999 9999 0 9999 5 3 0 0 0 0 0
4 1 2 3 0 1 4 0 1 1 0 0
5 2 3 4 1 0 5 4 4 4 0 0

1 2 3 4 5 1 2 3 4 5
1 0 1 2 3 2 1 1 2 2 2 2
2 3 0 1 2 1 2 5 2 3 5 5
3 7 8 0 6 5 3 5 5 3 5 5
4 1 2 3 0 1 4 1 1 1 4 5
5 2 3 4 1 0 5 4 4 4 4 5

Figura 20: Matrizes do Algoritmo de Floyd-Warshall

Tendo criado a matriz com os caminhos mínimos, já podemos encontrar


uma rota entre dois pontos do grafo. Por exemplo, o caminho mais curto entre o
ponto-origem 1 e o ponto-destino 4 é 1-2-5-4. E pela matriz com as menores
distâncias podemos ver que a distância desse percurso é de 3. Portanto, para
futuras gerações de rota, a matriz que nos interessa e que será gravada no banco
de dados é a matriz com os caminhos mínimos.

5.1.2 Geração do banco de dados e roteirização: Dijkstra

O Algoritmo de Dijkstra trabalha de forma semelhante ao Floyd-Warshall


durante a criação dos dados utilizados para a posterior roteirização, com a
40

diferença que ele trabalha com vetores e não matrizes, por ter como objetivo achar
o menor caminho de um ponto para qualquer outro do grafo, e não de qualquer
ponto para qualquer outro.
Inicialmente, define-se qual será o vértice raiz. O vetor inicial contém os
valores das distâncias de todos os outros vértices até o vértice-raiz, sendo que o
valor para os vértices que não fazem ligação direta com o raiz é definido como
infinito (ou um valor muito alto). Conforme o algoritmo é executado, dois vetores
são utilizados para guardar as distâncias e os caminhos mínimos entre os demais
vértices e o vértice-raiz.

Figura 21: Algoritmo de Dijkstra em execução sobre o grafo G

A figura 21 representa a seqüência de vértices que são ‘visitados’ durante a


execução do Algoritmo de Dijkstra. Primeiro, grava-se nos vetores (figura 22)
quais são os vizinhos do vértice-raiz, indicando a distância deste até a raiz no
vetor de menores distâncias, em seguida é gravado no vetor de caminhos
mínimos que esses vértices estão diretamente ligados ao raiz.
Entre os vértices vizinhos do raiz, pega-se o de menor distância (nó-cinza
na figura 21) e faz o mesmo que foi feito para o raiz, ou seja, é informada qual a
41

distância desse novo vértice até o nó-cinza. É somada essa distância com a
distância entre o nó-cinza e o nó-raiz, e essa é a distância que será gravada no
vetor de menores distâncias.

Vetor com as menores distâncias Vetor com os caminhos mínimos


1 2 3 4 5 1 2 3 4 5
1 0 1 9999 5 9999 1 1 1 - 1 -

1 2 3 4 5 1 2 3 4 5
1 0 1 2 5 2 1 1 1 2 1 2

1 2 3 4 5 1 2 3 4 5
1 0 1 2 5 2 1 1 1 2 1 2

1 2 3 4 5 1 2 3 4 5
1 0 1 2 3 2 1 1 1 2 5 2

1 2 3 4 5 1 2 3 4 5
1 0 1 2 3 2 1 1 1 2 5 2

Figura 22: Vetores do Algoritmo de Dijkstra

Ao fim das iterações, obtém-se os dois vetores com os conteúdos que


serão utilizados para encontrar um caminho entre o vértice-raiz e qualquer outro
vértice do grafo.
Para o exemplo, acharemos o caminho entre a origem 1 e o destino 4 no
vetor de caminhos mínimos, observando que esse caminho será dado de trás para
a frente. Pega-se o valor que está no quarto índice. O valor é o 5, portanto o
próximo passo da rota está no quinto índice. No quinto está o valor 2 e no
segundo índice o valor 1. Enfim a rota é formada: 4-5-2-1, ou 1-2-5-4 no sentido
correto.
42

5.1.3 Geração do banco de dados e roteirização: BuscaCuritiba

Como o Algoritmo BuscaCuritiba trabalha com coordenadas de um plano


cartesiano, o grafo G deve informar, ao invés das distâncias entre os vértices
vizinhos, as coordenadas x e y de cada vértice que o compõe. O banco de dados
utilizado na roteirização será formado por duas tabelas, uma que informa quais
são os vizinhos de um vértice e outra que traz as informações geográficas de cada
vértice, ou seja, seus x e y. Essas duas tabelas estão descritas no item 2.2.2:
tabela 2 e tabela 3.
Assim que o grafo esteja corretamente inserido no banco com as
informações necessárias para o funcionamento do algoritmo, a roteirização entre
origem e destino passados se dá através dos cálculos de menor distância entre os
dois pontos no plano cartesiano. Por exemplo, para formar a rota entre o ponto-
origem 1 e o ponto-destino 4, do grafo G, seriam procurados todos os vizinhos do
ponto de origem e calculadas as suas distâncias até o ponto de destino, para
saber qual o vizinho mais perto do destino, e assim começar a formação da rota
que será utilizada.
Como pode ser observado por esse exemplo, o Algoritmo BuscaCuritiba
corre o risco de encontrar prematuramente o ponto-destino e parar a roteirização,
gerando uma rota maior da que a gerada pelos algoritmos de Floyd-Warshall e
Dijkstra. No exemplo, os outros dois algoritmos fizeram a rota 1-2-5-4 com uma
distância de 3, já o BuscaCuritiba fez a rota 1-4 com uma distância de 5. Isso
explica o fato dos gráficos do item 5.2 mostrarem os dois algoritmos tradicionais
com rotas de melhor qualidade, embora, por vezes, com maior número de
esquinas utilizadas.

5.2 CASOS DE TESTES

Foram desenvolvidos dois programas (anexos nos apêndices B e C), cada


um operando com um determinado algoritmo. Basicamente, os programas
recebem duas coordenadas (uma de origem e uma de destino) entre as quais se
43

traçará uma rota e, como resposta, exibem qual foi a rota calculada, o tempo de
execução dos cálculos e qual a distância percorrida.
Foram traçadas 15 rotas distintas entre si pela distância percorrida e
anotados os tempos de execução em milissegundos gastos pelos três algoritmos
para o cálculo de cada rota, a distância percorrida, que não recebe uma unidade
de medida por se tratar da distância entre dois pontos calculada pela fórmula da
geometria analítica, e o número de quadras que compõem a rota traçada.
Uma observação importante é que os testes foram realizados em acessos
exclusivos, ou seja, os gráficos, a seguir apresentados, representam a atuação de
cada algoritmo sendo requisitado por um único cliente.
As 15 rotas foram escolhidas por representarem todas as possibilidades de
caminhos: origem e destino iguais; origem e destino na mesma quadra; origem e
destino na mesma rua; origem e destino em distâncias pequenas; e origem e
destino em distâncias grandes. Os pontos foram selecionados de maneira a
explorar a maior parte possível das ruas disponíveis.
Os dados coletados basearam os três gráficos a seguir, que relacionam os
15 casos da amostragem, primeiramente, com o tempo de execução dos três
algoritmos, em seguida, com as distâncias percorridas pelas rotas calculadas, e,
por último, com a quantidade de quadras percorridas pelas rotas calculadas.
Para uma melhor análise os 15 casos foram ordenados pela distância entre
as coordenadas de origem e de destino. Dessa maneira, o caso 1 representa o
caso em que origem e destino estão mais próximos e o caso 15 em que estão
mais distantes.
Relacionando os casos com o tempo de execução dos algoritmos (Figura
23), nota-se que o algoritmo BuscaCuritiba demanda mais tempo de execução
conforme se aumenta a distância entre origem e destino. Em contrapartida, o
algoritmo de Dijkstra demonstra regularidade nos tempos dispendidos por suas
rotas calculadas, apresentando uma média de aproximadamente 300
milissegundos em cada caso. O algoritmo de Floyd-Warshall apresenta os tempos
mais elevados em 7 casos e o tempo mais elevado de todos: 688 milissegundos.
44

800

700

600

500
Tempo (ms)

Busca Curitiba
400 Floyd-Warshall
Dijkstra
300

200

100

0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Casos

Figura 23: Gráfico de comparação dos tempos de execução dos algoritmos

Pelo gráfico da Figura 24, ao relacionar os casos da amostragem com as


distâncias percorridas pelas rotas calculadas, observa-se que em todos os casos
os algoritmos de Dijkstra e Floyd-Warshall calculam rotas com distâncias iguais.
Em nenhum dos casos o algoritmo de BuscaCuritiba foi superior aos demais
algoritmos, apresentando em alguns casos rotas mais distantes que as calculadas
pelos outros.

700

600

500

400 Busca Curitiba


Distância

Floyd-Warshall
300 Dijkstra

200

100

0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Casos

Figura 24: Gráfico de comparação das distâncias percorridas pelas rotas dos algoritmos
45

Ao comparar a quantidade de quadras percorridas entre as 15 rotas


calculadas (Figura 25), observa-se que, conforme o gráfico anterior, os algoritmos
de Floyd-Warshall e Dijkstra apresentam resultados idênticos. Em 4 casos o
algoritmo de BuscaCuritiba apresenta o melhor resultado, em 4 casos apresenta o
pior e nos casos restantes obteve o mesmo resultado dos demais algoritmos.

30

25

20

Busca Curitiba
Quadras

15 Floyd-Warshall
Dijkstra

10

0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Casos

Figura 25: Gráfico de comparação das quadras percorridas pelas rotas dos algoritmos

Com base nos resultados obtidos e nas observações dos gráficos conclui-
se que o algoritmo de BuscaCuritiba é mais eficiente em termos de tempo de
execução que o algoritmo de Floyd-Warshall na maioria dos casos. Em relação ao
algoritmo de Dijkstra, o BuscaCuritiba apresenta maior eficiência até certo ponto,
pois à medida em que se aumenta a distância entre os pontos de origem e destino
da rota, o algoritmo demanda maior tempo de execução.
Na amostragem utilizada para as comparações, o Dijkistra torna-se mais
eficiente a partir do momento em que as distâncias entre os pontos de origem e
destino da rota atinge o valor de 700. Isso se deve ao fato de o algoritmo de
BuscaCuritiba repetir uma cadeia de comandos em um laço while a cada quadra
adicionada à rota. Assim sendo, o algoritmo torna-se mais dispendioso à medida
46

em que a rota almejada aumenta.


Por outro lado, isso não ocorre com o algoritmo de Dijkstra, pois, como
mencionado anteriormente, ele apresenta uma constância no cálculo de suas
rotas. Essa regularidade explica-se pela estrutura do algoritmo, composta por dois
laços for e um laço while que executa apenas quatro instruções a cada iteração. A
quantidade de iterações dos laços for mantém-se constante para o cálculo de
rotas diferentes e é definida pelo número de vértices do grafo, ou seja, o algoritmo
de Dijkstra demanda maior tempo de execução somente com o aumento do
número de vértices.
Com o experimento e a análise da estrutura do algoritmo de Dijkstra foi
observado que o tamanho da rota não influencia o tempo de execução do
algoritmo, o que o torna mais eficiente em relação ao BuscaCuritiba na medida em
que aumenta a distância percorrida pela rota.
Em relação à qualidade das rotas calculadas, o algoritmo proposto neste
trabalho mostra-se um pouco menos eficiente que os demais, porém trata-se de
uma diferença de pequena magnitude.
Levando em conta o armazenamento das informações necessárias para o
cálculo das rotas no banco de dados, observa-se que o algoritmo de Floyd-
Warshall ocupa um espaço em disco consideravelmente maior comparando-o ao
BuscaCuritiba. Para medir essa diferença foi utilizado o bairro Centro de Curitiba,
escopo deste trabalho, como amostra.
O algoritmo de Floyd-Warshall armazena em banco de dados uma matriz n
x n, em que n equivale ao número de vértices do grafo. Para o experimento, cada
esquina do bairro Centro foi considerada um vértice e o conjunto de todas as
esquinas corresponde ao grafo.
Considerando que esse bairro possui 257 esquinas e que o algoritmo de
Floyd-Warshall armazena as distâncias entre todos os seus vértices, obtemos um
total de 66049 registros a serem armazenados em banco de dados. Isso equivale
a 3,7 MB de espaço em disco e para popular uma tabela de dados com tal
quantidade de informações foram gastos aproximadamente 3 minutos.
Diferentemente do algoritmo de Floyd-Warshall, o BuscaCuritiba armazena
47

apenas as relações de adjacência entre os vértices, ou seja, cada registro do


banco de dados relaciona uma determinada esquina a uma esquina adjacente.
Para o experimento citado, isso corresponde a um total de 913 registros gerados e
63,3 KB de espaço em disco ocupados. O tempo gasto para popular uma tabela
com tais registros foi de 93 ms.
Ao tomar uma amostra de maiores proporções, percebe-se que o banco de
dados gerado pelo algoritmo de Floyd-Warshall pode atingir valores
extraordinários de ocupação de espaço em disco e tempo para armazenamento
das informações. Estima-se que para a cidade de Curitiba, por exemplo, que na
sua totalidade possui 75 bairros, os dados gerados pelo algoritmo ocupem 278
MB, sendo necessárias aproximadamente 4 horas para seu armazenamento.
Por meio deste experimento conclui-se que o algoritmo BuscaCuritiba
apresenta a vantagem de ocupar menos espaço em disco com informações
necessárias para o cálculo de suas rotas. Isso resulta em economia de tempo para
popular o banco de dados.
A forma como essas informações são armazenadas também facilitaria
futuras expansões do grafo. No caso do Algoritmo de Floyd-Warshall, a inclusão
de novos vértices acarretaria a restruturação total do banco de dados e o
acréscimo do tempo gasto para populá-lo. Em contrapartida, ao BuscaCuritiba a
expansão do grafo resultaria apenas na inclusão dos novos vértices e suas
adjacências ao banco de dados.
48

6. DESENVOLVIMENTO DO SISTEMA

Neste item estão descritos o funcionamento e o desenvolvimento do


sistema, mostrando como é a interação com o usuário, quais foram os algoritmos
utilizados, além de alguns comentários sobre o projeto e o seu cronograma.

6.1 INTERAÇÃO INICIAL COM O USUÁRIO

O usuário inicialmente precisa preencher um formulário com as informações


necessárias para o cálculo da rota desejada. O formulário é composto por quatro
caixas de texto e uma combo box. Nas caixas de texto são requisitados os nomes
e os números das ruas de origem e destino, na combo box é solicitada a forma
desejada de roteirização dentre três opções: a pé, de carro e de ônibus.

Figura 26: Página de preenchimento inicial dos dados

A consistência dos dados informados é garantida por um mecanismo


oferecido pela tecnologia WML que restringe ao usuário digitar letras nos campos
que solicitam os números das ruas. Caso os nomes de ruas informados não sejam
encontrados no banco de dados, o usuário será redirecionado para uma página
que o informará do erro cometido.
49

Figura 27: Página informando que os endereços não foram encontrados

Após esse processo, caso todas as informações fornecidas estejam


corretas, o usuário é direcionado para a página de confirmação dos dados. Essa
página tem sua utilidade devido ao fato de algumas ruas possuírem parte de seus
nomes iguais aos de outras. Por essa razão, o novo formulário apresenta ao
usuário quatro combo boxes para que ele confirme dentre as opções quais são as
ruas de origem e destino desejadas.

Figura 28: Página de confirmação dos dados

Após a confirmação dos dados, dá-se início ao algoritmo de cálculo de


rotas, e finalmente a tela com a rota que deve ser seguida é mostrada ao usuário.
50

Figura 29: Página com o resultado da roteirização

6.2 ALGORITMOS

Foram desenvolvidos três algoritmos de roteirização diferentes para a


realização do trabalho: para cálculo de rotas a pé, para cálculo de rotas de ônibus
e para cálculo de rotas de carro.
O “Algoritmo de Rotas a Pé” inicialmente determina a esquina de origem
mais próxima do destino dentre as duas que lhe são fornecidas. Em seguida, ele
busca no banco de dados os vizinhos da esquina de origem e os ordena pela
distância até o destino. O vizinho que possui a menor distância até o destino é
armazenado no vetor que possui as esquinas que formam a rota. Esse vizinho
recém armazenado é utilizado para a busca dos novos vizinhos e o processo se
repete até que um dos vizinhos coincida com uma das duas esquinas de destino.
51

// busca, entre as duas esquinas de origem, qual está mais próxima do destino
esquina_o = buscarMaisProxima();
f = 0;
rota[f] = esquina_o;
enquanto (rota[f] for diferente de destino) {
// busca os vizinhos da esquina
vizinhos[] = buscaVizinhos(rota[f]);
// ordena os vizinhos por ordem de proximidade com o destino
vizinhos[] = ordenarVetor(vizinhos);
f++;
rota[f] = vizihnos[0];
}
// a rota está guardada no vetor rota[]

Figura 30: Pseudo-código do Algoritmo de Rotas a Pé

O “Algoritmo Para Carros” foi projetado para encontrar a melhor rota entre a
origem e o destino, portanto não é o seu objetivo encontrar o menor caminho.
Para roteirizar para carros deve-se levar em consideração o sentido das ruas,
contudo outras observações devem ser feitas para que o roteirizador aja como se
fosse um motorista seguindo o fluxo do trânsito. Para tanto, o algoritmo foi
desenvolvido para encontrar a rota que utilize um número menor de ruas,
seguindo pela maior distância possível na mesma rua. O seu funcionamento é o
seguinte: primeiro encontram-se os dois melhores vizinhos (mais próximos do
destino) da esquina atual (Alfa e Beta); verifica-se se Alfa está em alguma das
ruas de alguma das esquinas de destino e se pode alcançá-las através dessa rua;
se sim, Alfa é o melhor caminho e o roteirizador irá encontrar a rota a partir de
Alfa; se não, faz a mesma verificação para Beta, seguindo a mesma lógica. Não
estando nem Alfa e nem Beta em alguma das ruas do destino, segue o algoritmo.
Pegam-se todos os vizinhos de Alfa, um a um, e verifica-se se esse novo vizinho
está em alguma das ruas do destino. A verificação é feita em todos os vizinhos de
52

Alfa que estejam em alguma das ruas que Alfa está, ou seja, quando a rua termina
ou muda de nome, descarta-se os vizinhos seguintes. A operação se repete para
o Beta. No final, se através de Alfa ou Beta consegue-se chegar até o destino
diretamente através de alguma esquina em alguma das ruas em que se
encontram Alfa e Beta, verifica-se a distância que deverá ser percorrida para
seguir para cada um dos caminhos (de Alfa e de Beta) e escolhe-se o menor entre
eles. Se não encontrou rua diretamente ligada a alguma das ruas de destino
seguindo o procedimento descrito, pega-se Alfa e retorna ao começo do algoritmo,
ou seja, pegam-se os dois melhores vizinhos de Alfa, o novo Alfa e o novo Beta e
começa tudo de novo.

Figura 31: Exemplo gráfico de uma rota do Alg. Para Carros

O “Algoritmo Para Ônibus” funciona da seguinte maneira: primeiramente,


procuram-se os x (valor que pode ser configurado conforme a situação) pontos de
ônibus mais próximos de uma das esquinas de destino, mas somente os pontos
de ônibus com uma distância menor que y (valor também configurado conforme a
situação) são usados. Assim que algum ponto de ônibus é encontrado (ao menos
53

um ponto é obrigatoriamente usado, independente de sua distância com as


esquinas de destino), tenta-se encontrar uma linha direta entre tal ponto e algum
dos pontos de ônibus mais próximos da origem (também seguindo a lógica dos
números x e y). Se achar uma linha direta, guarda essa linha e seu tamanho
(distância medida em número de pontos entre o ponto de origem e o de destino)
em um vector para posterior ordenação com as demais linhas encontradas. Se
não achar nenhuma linha direta, começa a verificar se algum dos pontos da linha
que contém o ponto de destino possui uma linha direta até a origem (nesse caso,
já é estabelecido que será necessário ao menos dois ônibus para a rota). Nessa
parte o algoritmo fica em loop até encontrar uma rota. Após guardar as x rotas, é
realizada uma ordenação para encontrar a melhor entre elas, considerando como
melhor a que possua o menor número de ônibus usados e o menor número de
pontos de ônibus.

// achar DESTINO

int numPtsIni_D = 10;


int distMax_D = 200;

1) pegar os numPtsIni_D mais próximos do usuário


/* Obs.: apenas pega o ponto se este estiver a menos de distMax_D metros
distante do usuário. */
2) no momento em que pega o ponto chama o método que vai achar a origem,
passando como parâmetro o id do ponto de destino em questão
3) será retornado um vector com a rota de ônibus a ser feita, sendo que
o primeiro índice desse vector informa quantos ônibus foram utilizados e
o segundo índice qual a distância percorrida.
4) ao final da geração das rotas, ordena o vector pelo menor número de
ônibus utilizados e posteriormente pela menor distância percorrida.

// achar ORIGEM

Vector getOrigem(id_destino) {

int numPtsIni_O = 10, contaPtsIni_O = 0, ponteiro = 0, ponteiroPai = 0,


numDeViz = 0;
int numPontosMin_O = 2; distMax_O = 200;
boolean fim = false;
Vector onibusVect, rotaFinalVect;

1) pegar os numPtsIni_O mais próximos do usuário


/* Obs.: apenas pega o ponto se este estiver a menos de distMax_O metros
distante do usuário, embora seja preciso pegar ao menos numPontosMin_O
pontos de origem. O contaPtsIni_O vai recebendo o número de pontos usados
até o momento, portanto, se 9 pontos foram encontrados o valor do
54

contaPtsIni_O será 9. */
2) no momento em que pega o ponto verifica se este possui conexão direta
com o destino, só então pega o próximo
3) se (o ponto buscado tiver conexão direta) {
fim = true; //fim;
}
4) senão {
coloca o ponto no vector onibusVect;
}
/* Obs.: talvez seja preciso ordenar o vector onibusVect por ordem de
proximidade ponto->usuário no final da busca dos numPtsIni_O pontos.
Obs2.: os pontos serão guardados da seguinte forma no vector:
"id_ponto,pai". Nesse formato, o id_ponto é o id buscado no banco de
dados e o pai é uma marcação para posteriormente saber quais ônibus foram
pegos para chegar no destino. Para os pontos iniciais o pai deverá ir com
o valor -1. */
5) /* se chegou até aqui é porque o usuários irá utilizar no mínimo 2
ônibus */
ponteiro = contaPtsIni_O
6)
while (!fim) {
6.1 - incluir no vector onibusVect todos os vizinhos do ponto que
está na posição ponteiro do vector onibusVect.
/* Obs.: como nos pontos iniciais, incluir assim: "id_ponto,pai",
sendo que aqui o pai será o valor de ponteiroPai. */
6.2 - antes de incluir, verificar se o ponto já está no vector, se
sim, não inclui. O numDeViz vai recebendo o número de pontos vizinhos
encontrados, como o contaPtsIni_O no começo.
6.3 - for (int cont = ponteiro; cont < (ponteiro + numDeViz); cont++)
{
/* verifica se o ponto que está na posição cont no vector
onibusVect tem conexão direta */
se (tem conexão direta) {
fim = true;
// fim;
/* para saber qual a rota usada, deverá fazer: pegar o
valor do pai desse ponto no vector onibusVect e se esse valor for
diferente de -1, pegar o pai do pai, repetindo esse procedimento até
encontrar o valor -1. Guardar todos os valores no vector rotaFinalVect.
*/
/* colocar no índice 1 do vector rotaFinalVecta o número
de ônibus usados e no índice 2 a distância percorrida. */
}
}
ponteiroPai++;
ponteiro = (ponteiro + numDeViz);
fim = false;
}
return rotaFinalVect;
}

Figura 32: Pseudo-código de parte do Algoritmo Para Ônibus

Após o uso de algum dos algoritmos de roteirização, o sistema passa a


55

utilizar o algoritmo que irá informar o caminho que deverá ser seguido.
O “Algoritmo Informante” funciona da seguinte forma: pega-se o vetor que
foi utilizado para guardar os pontos (esquinas) pelo algoritmo de roteirização
utilizado; um novo vetor irá guardar o nome da quadra entre o ponto 01 e o ponto
02 do vetor, depois entre o ponto 02 e o ponto 03, e assim até guardar o nome de
todas as quadras (nome das ruas) por onde a rota passa; a mensagem que será
enviada para o usuário é formada lendo-se as quadras que foram gravadas no
vetor, por exemplo, “Inicie pela Avenida Sete de Setembro por 3 quadras até o
número 3555, siga pela Avenida Marechal Floriano...”. O número de quadras é
obtido observando a repetição do nome da quadra em uma seqüência do vetor.
Os números são obtidos através do próprio vetor com as quadras, uma vez que
quando a quadra é gravada no vetor sua numeração é guardada junta.

6.3 COMENTÁRIOS SOBRE O DESENVOLVIMENTO

Durante o desenvolvimento desse trabalho, a equipe se deparou com


algumas dificuldades que não estavam previstas, atrapalhando o andamento do
projeto e desviando a atenção das atividades programadas para o ajuste de
detalhes que impediam a realização das tarefas.

6.3.1 Codificação dos Caracteres

Em relação à codificação dos caracteres nos deparamos com dois


problemas: o retorno das informações do banco de dados e a passagem de
parâmetros entre as páginas do site WAP.
Quando o usuário informava a rua de destino ou origem na tela inicial e
aguardava a confirmação dos dados enviados, muitas vezes nada era retornado,
embora o nome das ruas estivessem corretos. Depois de exaustivos testes, a
equipe descobriu que o problema era a codificação utilizada pelo banco de dados
PostgreSQL, a qual por padrão é UTF-8. Para resolver esse problema bastou
modificar o tipo da codificação do banco de dados utilizado para LATIN-1.
56

Quanto ao problema de passagem de parâmetros, o que ocorria era a não


interpretação de caracteres como “~”, “ç” e acentuações em geral pela página
WML na leitura de parâmetros passados pela URL, embora a sua codificação
estivesse configurada para ISO-8859-1. A solução do problema foi utilizar a tag
<postfield> que simula uma passagem de parâmetros ocultos, como no método
post do HTML. Devido à falta de bons exemplos de utilização de WML, a equipe
perdeu demasiado tempo para descobrir muitas das tags utilizadas no sistema.

6.3.2 Limitação de Hardware

Durante a maior parte do tempo o computador utilizado para os testes do


sistema foi um AMD Athlon XP 2.2 com 256 MB de memória RAM, utilizando o
sistema operacional Windows XP Professional, sendo que o ideal seria possuir ao
menos 512 MB de memória. Isso afetou diretamente o andamento do projeto, pois
resultou em perda de tempo com a compilação do sistema, uma vez que a cada
alteração de uma das servlets, o servidor web deveria ser reinicializado. Esse
processo ocupava um tempo fora dos padrões normais, pois não havia memória
suficiente para suportar a execução do ambiente de desenvolvimento NetBeans e
o emulador para celulares.

6.3.3 Levantamento dos Dados

Muitas informações necessárias para a realização do projeto mostraram-se


de difícil acesso. Ao longo do tempo de execução do trabalho não foram
encontradas bases de dados contendo os nomes das linhas de ônibus da cidade
relacionadas à localização de seus respectivos pontos. Tais informações, de
extremo caráter de importância, foram obtidas pela observação de mapas que
forneciam o itinerário dos ônibus e por anotações manuais através de pesquisa
pelas ruas contidas no escopo geográfico do projeto.
57

6.3.4 Cache nas Páginas WAP

As páginas do sistema armazenavam em cache as informações passadas


em um formulário, o que resultava na passagem de dados incorretos para a
página seguinte. A solução adotada foi a remoção dos dados armazenados nos
formulários a cada vez que eram acessados, por meio de um mecanismo da
própria WML.

6.3.5 Cronograma do Projeto

O cronograma proposto para a realização deste trabalho foi seguido à risca,


porém algumas atividades sofreram atrasos. Inicialmente, a pesquisa sobre
construção de páginas WAP demandou uma semana a mais do previsto devido a
dificuldade em se encontrar material relevante a respeito do assunto.
A estruturação do banco de dados retardou em uma semana o cronograma.
O atraso foi devido a algumas reestruturações nas tabelas de dados, necessárias
para abrigar informações imprescindíveis ao algoritmo de roteirização não
previstas.
O desenvolvimento do algoritmo de roteirização foi a atividade que mais
demandou tempo a mais do que o previsto: aproximadamente 3 meses. Durante a
realização dessa etapa do projeto notou-se a necessidade de segmentar o
algoritmo de roteirização em três algoritmos, cada um dedicado a um determinado
tipo de rota: a pé, de carro e de ônibus.
Para manter a eficiência do algoritmo de rotas a pé, os algoritmos de rotas
de carro e de ônibus precisaram ser repensados. A elaboração dos novos
algoritmos demandou tempo e a reestruturação do banco de dados.
A figura 33 mostra um comparativo entre o cronograma inicialmente
definido e o cronograma real das atividades:
58

Cronograma Ideal Cronograma Real

Figura 33: Cronograma idealizado no pré-projeto (à esquerda) e cronograma realizado (à


direita)
59

7. CONCLUSÃO

Finalizado o projeto, observa-se que o produto final representa em sua


grande parte o que foi planejado e segue as especificações pré-estabelecidas
através da modelagem do sistema.
O sistema atual apresenta-se pouco útil para o usuário final, pois apenas
pode ser utilizado para um único bairro da cidade de Curitiba, contudo, a estrutura
em que foi desenvolvido oferece grande possibilidade de expandi-lo, necessitando
apenas da inclusão das informações (nomes de ruas, etc) no banco de dados.
Com algumas alterações, muitas outras funcionalidades podem ser
agregadas ao sistema atual, entre elas: a utilização de uma imagem do mapa com
o desenho da rota a ser seguida, para celulares mais capacitados ou mesmo para
navegadores de desktop; o sistema de buscas pode ser incrementado para que o
usuário não precise escrever o nome da rua na qual está ou para a qual pretende
ir, e sim apenas o nome de alguma referência, por exemplo ‘UTFPR’; a
disponibilização de uma seção na qual o usuário possa encontrar um destino não-
fixo, por exemplo, um hotel, mas não um hotel em particular. Assim o sistema
traria os hotéis mais próximos de onde o usuário está, informando qual a rota que
deve ser feita para chegar ao hotel escolhido.
O sistema poderia futuramente ser utilizado comercialmente através de uma
das seguintes opções:

1) A exemplo de alguns produtos de sucesso recente, como o Skype,


poder-se-ia utilizar a forma mais rápida e direta de retorno: a venda do
sistema para alguma empresa interessada, como, por exemplo, algum
portal regional.
2) Também seguindo fórmulas prontas, outra alternativa seria, como o
portal da empresa MapLink, cobrar pelo serviço, exigindo que o usuário
seja cadastrado e pague uma mensalidade para que possa utilizar o
sistema.
3) O sistema poderia ser um ‘fortalecedor de marca’, sendo usado como
60

um chamariz de clientes para um outro sistema (site convencional, por


exemplo). A marca BuscaCuritiba poderia ser usada como nome de um
portal, fazendo com que o sistema para dispositivos móveis fixasse essa
marca na memória dos usuários, tornando-a conhecida e procurada.
4) Em uma segunda fase do sistema, seria desenvolvida uma forma de
busca por um ‘destino genérico’, onde o usuário não precisaria digitar o
destino explicitamente em forma de endereço, e sim apenas como uma
indicação. Por exemplo, poderia ser digitado ‘hotel’ no campo destino,
sendo então buscados pelo sistema todos os hotéis que estejam em um
raio de x metros da origem passada pelo usuário. Nessa lista de hotéis
retornada como resposta, estariam em primeiro lugar e em destaque os
hotéis que pagassem por esse destaque, e em uma segunda página os
demais hotéis.
5) Um contrato de prestação de serviços poderia ser firmado com alguma
das grandes operadoras de telefonia que atuam em Curitiba, fazendo
com que apenas usuários dessa determinada operadora pudessem
acessar o sistema. A arrecadação seria proporcional ao número de
acessos ao sistema.
61

REFERÊNCIAS

ARAÚJO, Jário. Desenvolvendo para WAP com WML. 2001. Rio de Janeiro:
Editora Ciência Moderna.

BASHAM, Bryan. Use a Cabeça! Servlet & JSP. 2005. Editora Alta Books.

BIAZUS, Diogo de Oliveira. PostgreSQL – Introdução e história. 2006. Artigo


publicado em 07/11/2006. Disponível em: http://www.postgresql.org.br. Acessado
em: 12/02/2007.

CHEN, Peter. Gerenciando Banco de Dados: A Abordagem Entidade


Relacionamento Para Projeto Lógico. 1990. Editora McGraw-Hill Ltda.

CORMEN, Thomas H. Introduction to Algorithms. 1990. The MIT Electrical


Engineering and Computer Science Series.

CUNHA, C. B. Aspectos Práticos da Aplicação de Modelos de Roteirização de


Veículos a Problemas Reais. 2001. Artigo publicado em 26/01/2001. Disponível
em: ptr.usp.br/docentes/cbcunha/files/roteirizacao_aspectos_praticos_CBC.pdf
Acessado em 28/03/2007.

FORTA, Ben et al. Desenvolvendo WAP com WML e WMLScript. Traduzido por:
Daniela Lacerda, Sônia Milione, Valéria Chamon. 2000. Rio de Janeiro: Campus.

JEVEAUX, Paulo. Tutorial de Servlets – Introdutório. 2004. Artigo publicado em


27/01/2004. Disponível em: http://www.portaljava.com.br. Acessado em:
12/02/2007.

LOUREIRO, Rafael. Administração de SGBD: Um Estudo de Caso. 2005.


Trabalho de Conclusão de Curso publicado em Agosto de 2005. Disponível em:
62

http://www.cin.ufpe.br/~tg/2005-1/rdal.pdf. Acessado em: 13/02/2007

MARIANI, Antonio. Algoritmo de Dijkstra para cálculo do Caminho de Custo


Mínimo. 2000. Artigo publicado em 29/05/2000. Disponível em:
http://www.inf.ufsc.br/grafos/temas/custo-minimo/dijkstra.html. Acessado em:
01/04/2007.

NOKIA. Nokia Mobile Internet Toolkit - Versão 4.1 - User’s Guide. 2004.

NONATO, Luis G. Algoritmo de Dijkstra. 2004. Artigo publicado em 04/05/2004.


Disponível em: http://www.lcad.icmc.usp.br. Acessado em: 08/03/2007.

SAMPAIO, Rudini Menezes. YANASSE, Horácio Hideki. Estudo e implementação


de algoritmos de roteamento sobre grafos em um sistema de informações
geográficas. 2002. Artigo publicado em 18/12/2002. Disponível em:
http://arxiv.org/ftp/cs/papers/0505/0505031.pdf. Acessado em 28/03/2007.

SHARMA, Chetan. Aplicações Comerciais da Internet Sem Fio (Wireless


Technology). 2001. Editora MAKRON Books Ltda.

TELEMACO, Ulisses. O que é JSP. 2004. Artigo publicado em 01/01/2004.


Disponível em: http://www.jspbrasil.com.br. Acessado em: 12/02/2007

TEMPLE, André. MELLO, Rodrigo. CALEGARI, Danival. SCHIEZARO, Maurício.


Programação Web com JSP, Servlets e J2EE. 2004.

W3SCHOOLS. WAP / WML Tutorial. 2007. Artigo publicado em 18/02/2007.


Disponível em: http://www.w3schools.com/wap/. Acessado em: 02/11/2006.
63

APÊNDICE A: CÓDIGO DA PÁGINA INDEX.JSP

<%@ page import="java.io.*,java.util.*" %>


<% response.setContentType("text/vnd.wap.wml"); %>
<% response.setCharacterEncoding("ISO-8859-1"); %>
<% response.setHeader("Cache-Control","no-cache"); %>

<?xml version="1.0" encoding="ISO-8859-1"?>


<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">

<wml>
<card id="card1" ontimer="#card2" title="BuscaCuritiba">
<timer value="20"/>
<p align="center">
<br/><br/>Procurando alguma coisa em Curitiba?
</p>
</card>
<card id="card2" ontimer="#card3" title="BuscaCuritiba">
<timer value="30"/>
<p align="center">
<br/><br/><big>BuscaCuritiba</big>
</p>
</card>
<card id="card3" title="BuscaCuritiba">
<p>
<anchor>
iniciar <go href="#card4"/>
</anchor><br/>
<anchor>
ajuda <go href="#card4"/>
</anchor><br/>
<anchor>
outras informações <go href="#card4"/>
</anchor><br/>
<anchor>
fale conosco <go href="#card4"/>
</anchor><br/>
</p>
</card>
<card id="card4" title="BuscaCuritiba">
<onevent type="onenterforward">
<refresh>
<setvar name="origem" value=""/>
<setvar name="destino" value=""/>
<setvar name="num_origem" value=""/>
<setvar name="num_destino" value=""/>
<setvar name="tipo_roteirizador" value=""/>
</refresh>
</onevent>

<onevent type="onenterbackward">
<refresh>
<setvar name="origem" value=""/>
<setvar name="destino" value=""/>
64

<setvar name="num_origem" value=""/>


<setvar name="num_destino" value=""/>
<setvar name="tipo_roteirizador" value=""/>
</refresh>
</onevent>

<table border="1">
<tr>
<td>
Origem: <br/>
<input name="origem" size="15"/><br/>
n°: <input name="num_origem" size="5" format="5N"/><br/>
</td>
</tr>
<tr>
<td>
Destino: <br/>
<input name="destino" size="15"/><br/>
n°: <input name="num_destino" size="5" format="5N"/><br/>
</td>
</tr>
<tr>
<td>
<select name="tipo_roteirizador">
<option value="1">A pé</option>
<option value="2">De carro</option>
<option value="3">De Ônibus</option>
</select>
</td>
</tr>
<tr>
<td>
<br/>
<anchor>
[buscar]
<go href="jsp/confirma.jsp" method="post">
<postfield name="origem" value="$(origem)"/>
<postfield name="destino" value="$(destino)"/>
<postfield name="num_origem" value="$(num_origem)"/>
<postfield name="num_destino" value="$(num_destino)"/>
<postfield name="tipo_roteirizador" value="$(tipo_roteirizador)"/>
</go>
</anchor>
<anchor>
[voltar]
<go href="#card3"/>
</anchor>

</td>
</tr>
</table>
</card>
</wml>
65

APÊNDICE B: IMPLEMENTAÇÃO DO ALGORITMO DE FLOYD-WARSHALL


public class FloydWarshall {

// número de vértices (esquinas) do grafo


int n;
// matriz de adjacência, só usada se não for utilizar o banco de dados
int[][] C;
// matriz que guarda as distâncias entre dois pontos quaisquer no grafo
int[][] K;
// matriz que guarda o menor caminho entre dois pontos quaisquer do grafo
int[][] R;
// vetor que guarda todas os vértices (esquinas) do grafo
int[] Esquinas;
// vetor que guarda a rota final
int[] Rota = new int[100];
Calculadora calc;
ConexaoBD Banco = null;

public static void main(String[] args) {


new FloydWarshall();
}

public FloydWarshall() {
Banco = new ConexaoBD();
inicializarValores();
inicializarMatriz();
// só descomentar essas funções se não for usar o banco de dados
//popularMatriz();
//gerarMatrizInfinito();
//gerarMatrizFinal();
//converterVertice(175, 212);
// só descomentar a função inserirNoBanco se quiser gerar uma nova base!
//inserirNoBanco();
gerarRota(205, 254);
calcularDistanciaPercorrida();
}

public void gerarRota(int o, int d) {


int viz = -1, cont = 0, oAux = o;
Rota[cont] = o;
cont++;
long tempo_ini = System.currentTimeMillis();
while (viz != d) {
try {
String declar = "SELECT viz FROM floydRota WHERE o = "+oAux+" AND d = "+d;
Banco.rs1 = Banco.stat1.executeQuery(declar);
if (Banco.rs1.next()) {
viz = Banco.rs1.getInt("viz");
if (viz != o) {
Rota[cont] = viz;
cont++;
}
oAux = viz;
}
}
catch (Exception e){
System.out.println(e);
}
}
long tempo_fim = System.currentTimeMillis();
long tempo = tempo_fim - tempo_ini;

System.out.println("---> Rota Floyd/Warshall --->");


for (int cont2 = 0; cont2 < Rota.length; cont2++) {
if (Rota[cont2] == -1) {
break;
}
System.out.print(Rota[cont2]+" ");
66

}
System.out.println("\nTempo de execução: "+tempo);
}

public void calcularDistanciaPercorrida(){


int distancia = 0;
int num_vertices = 0;
for (int cont = 0; cont < (Rota.length - 1); cont++) {
num_vertices++;
if (Rota[cont] == -1 || Rota[cont + 1] == -1) {
break;
}
distancia += calc.getDistancia(Rota[cont], Rota[cont + 1]);
}
System.out.println("Número de esquinas: "+num_vertices);
System.out.println("Distância percorrida: "+distancia);
}

public void inserirNoBanco() {


//essa função coloca as duas matrizes geradas no banco
int contAux = 1, contAux2 = 1;
for (int cont = 0; cont < n; cont++) {
for (int cont2 = 0; cont2 < n; cont2++) {
// inserindo a matriz com as distancias: K[][]
String declar = "INSERT INTO floydDistancia VALUES ("+Esquinas[cont]+", "+Esquinas[cont2]+",
"+K[cont][cont2]+")";
try {
Banco.stat1.executeUpdate(declar);
contAux++;
}
catch (Exception e){
System.out.println(e);
}
// inserindo a matriz com as rotas: R[][]
declar = "INSERT INTO floydRota VALUES ("+Esquinas[cont]+", "+Esquinas[cont2]+",
"+Esquinas[(R[cont][cont2]) - 1]+")";
try {
Banco.stat1.executeUpdate(declar);
contAux2++;
}
catch (Exception e){
System.out.println(e);
}
}
}
}

public void inicializarValores() {


String declar = "SELECT COUNT(id_esquina) FROM esquinas";
int num_esquinas = 0;
try {
Banco.rs1 = Banco.stat1.executeQuery(declar);
if (Banco.rs1.next()) {
num_esquinas = Banco.rs1.getInt("COUNT");
}
Banco.rs1.close();
}
catch (Exception e){
System.out.println(e);
}
n = num_esquinas; C = new int[n][n]; K = new int[n][n]; R = new int[n][n]; Esquinas = new int[n];
calc = new Calculadora();
}

public void popularMatriz() {


String declar = "SELECT id_esquina FROM esquinas";
int cont = 0, viz, vertice, distancia;

try {
Banco.rs1 = Banco.stat1.executeQuery(declar);
67

while (Banco.rs1.next()) {
Esquinas[cont] = Banco.rs1.getInt("id_esquina");
cont++;
}
Banco.rs1.close();
}
catch (Exception e){
System.out.println(e);
}
try {
for (int cont2 = 0; cont2 < n; cont2++) {
declar = "SELECT * FROM esquinas_vizinhos_ape WHERE id_esquina = "+Esquinas[cont2];
Banco.rs1 = Banco.stat1.executeQuery(declar);
while (Banco.rs1.next()) {
// pegando os vizinhos
viz = Banco.rs1.getInt("viz");
// calculando a distancia até esse vizinho
vertice = converterVertice2(viz);
System.out.println("Viz="+viz+" Vertice="+vertice);
C[cont2][vertice] = calc.getDistancia(Esquinas[cont2], viz);
}
}
Banco.rs1.close();
}
catch (Exception e){
System.out.println(e);
}
}

public int converterVertice2(int viz) {


for (int cont = 0; cont < n; cont ++) {
if (Esquinas[cont] == viz) {
viz = cont;
break;
}
}
return viz;
}
public void converterVertice(int e1, int e2) {
// converte o id das esquinas passadas para seus índices na matriz Esquinas[]
int v1 = 0, v2 = 0;
for (int cont = 0; cont < n; cont ++) {
if (Esquinas[cont] == e1) {
v1 = cont;
}
if (Esquinas[cont] == e2) {
v2 = cont;
}
}
gerarRotaPorMatriz(v1, v2);
}

public void gerarRotaPorMatriz(int v1, int v2) {


// gera a rota usando a matriz e não o banco de dados
int destino = -1, cont = 0, distancia = 0;
distancia += K[v1][v2];
Rota[cont] = Esquinas[v1];
cont++;

while(destino != (v2 + 1)) {


destino = R[v1][v2];
v1 = (destino - 1);
Rota[cont] = Esquinas[v1];
cont++;
}
System.out.println("### Rota ###");
for (int cont2 = 0; cont2 < Rota.length; cont2++) {
if (Rota[cont2] == -1) {
break;
}
68

System.out.print(Rota[cont2]+" ");
}
System.out.println("\nDistância percorrida: "+distancia);
}

public void gerarMatrizInfinito() {


// primeiro passo do algoritmo de Floyd-Warshall
// Obs.: coloquei 999 representando o infinito.
for (int cont = 0; cont < n; cont++) {
for (int cont2 = 0; cont2 < n; cont2++) {
if (C[cont][cont2] == 0 && cont != cont2) {
K[cont][cont2] = 999;
}
else {
K[cont][cont2] = C[cont][cont2];
}
}
}
}

public void gerarMatrizFinal() {


// fim do algoritmo de Floyd-warshal (modificado)
// gera duas matrizes: uma com as distâncias (K[][]) e outra com as rotas (R[][])
for (int q = 0; q < n; q++) {
for (int s = 0; s < n; s++) {
for (int t = 0; t < n; t++) {
if ((K[s][q] + K[q][t]) < K[s][t]) {
K[s][t] = K[s][q] + K[q][t];
if (R[s][q] == 0) {
R[s][t] = (q+1);
}
else {
R[s][t] = R[s][q];
}
}
}
}
}

for (int cont = 0; cont < n; cont++) {


for (int cont2 = 0; cont2 < n; cont2++) {
if (R[cont][cont2] == 0){
R[cont][cont2] = (cont2 + 1);
}
}
}
}

public void inicializarMatriz(){


for (int cont = 0; cont < n; cont++) {
for (int cont2 = 0; cont2 < n; cont2++) {
if (cont == cont2) {
R[cont][cont2] = (cont + 1);
}
else {
R[cont][cont2] = 0;
}
C[cont][cont2] = 0;
}
}
for (int cont = 0; cont < Rota.length; cont++) {
Rota[cont] = -1;
}
}
}
69

APÊNDICE C: IMPLEMENTAÇÃO DO ALGORITMO DE DIJKSTRA

public class Dijkstra {


int n = 5, u, v;
int[][] S = new int[n][n]; int[][] d = new int[n][2];
int[] tt = new int[n];
int[] Esquinas, Rota;
ConexaoBD Banco = null;
Calculadora calc;
public static void main(String[] args) {
new Dijkstra();
}

public Dijkstra() {
Banco = new ConexaoBD();
inicializarValores();
inicializarMatriz();
popularMatrizBD();
converterVertice(254, 205); //destino, origem
calcularDistanciaPercorrida();
}

public void inicializarValores() {


String declar = "SELECT COUNT(id_esquina) FROM esquinas";
int num_esquinas = 0;
try {
Banco.rs1 = Banco.stat1.executeQuery(declar);
if (Banco.rs1.next()) {
num_esquinas = Banco.rs1.getInt("COUNT");
}
Banco.rs1.close();
}
catch (Exception e){}
n = num_esquinas; S = new int[n][n]; d = new int[n][2]; tt = new int[n]; Rota = new int[n]; Esquinas = new int[n];
calc = new Calculadora();
}

public int extrairMin(int[][] d3) {


int[][] dist = new int[n][2];
for (int cont = 0; cont < n; cont++) {
dist[cont][0] = d3[cont][0];
dist[cont][1] = d3[cont][1];
}

int indice = -1;


int ate = (dist.length - 1);
70

int[] aux = new int[2];


for (int cont = 0; cont < n; cont++) {
for (int cont2 = 0; cont2 < ate; cont2++) {
if (dist[cont2][0] > dist[cont2 + 1][0]) {
aux[0] = dist[cont2][0];
dist[cont2][0] = dist[cont2 + 1][0];
dist[cont2 + 1][0] = aux[0];
}
}
}
label: {
for (int cont = 0; cont < n; cont++) {
for (int cont2 = 0; cont2 < n; cont2++) {
if (dist[cont][0] == d[cont2][0] && d[cont2][1] == 0) {
indice = cont2;
d[cont2][1] = 1;
break label;
}
}
}
}
return indice;
}

public void gerarRota(int v1, int v2) {


long tempo_ini = System.currentTimeMillis();
for (int cont = 0; cont < n; cont++) {
tt[cont] = v1;
}
for (int cont = 0; cont < n; cont++) {
u = extrairMin(d);
for (int v = 0; v < n; v++) {
if (d[v][0] > (d[u][0] + S[u][v])) {
d[v][0] = (d[u][0] + S[u][v]);
tt[v] = u;
}
}
}
// gerou o vetor tt[] com os caminhos e o d[] com as menores distâncias
int destino = -1, cont = 0, distancia = 0;
Rota[cont] = Esquinas[v2];
cont++;

while(destino != (v1)) {
destino = tt[v2];
v2 = tt[v2];
Rota[cont] = Esquinas[v2];
71

cont++;
}
long tempo_fim = System.currentTimeMillis();
long tempo = tempo_fim - tempo_ini;
System.out.println("---> Rota Dijkstra --->");
for (int cont2 = 0; cont2 < Rota.length; cont2++) {
if (Rota[cont2] == -1) {
break;
}
System.out.print(Rota[cont2]+" ");
}
System.out.println("\nTempo de execução: "+tempo);
}

public void calcularDistanciaPercorrida(){


int distancia = 0, num_vertices = 0;
for (int cont = 0; cont < (Rota.length - 1); cont++) {
num_vertices++;
if (Rota[cont] == -1 || Rota[cont + 1] == -1) {
break;
}
distancia += calc.getDistancia(Rota[cont], Rota[cont + 1]);
}
System.out.println("Número de esquinas: "+num_vertices);
System.out.println("Distância percorrida: "+distancia);
}

public void popularMatrizBD() {


String declar = "SELECT id_esquina FROM esquinas";
int cont = 0, viz, vertice, distancia;
try {
Banco.rs1 = Banco.stat1.executeQuery(declar);
while (Banco.rs1.next()) {
Esquinas[cont] = Banco.rs1.getInt("id_esquina");
cont++;
}
Banco.rs1.close();
}
catch (Exception e){
System.out.println(e);
}
try {
for (int cont2 = 0; cont2 < n; cont2++) {
declar = "SELECT * FROM esquinas_vizinhos_ape WHERE id_esquina = "+Esquinas[cont2];
Banco.rs1 = Banco.stat1.executeQuery(declar);
while (Banco.rs1.next()) {
viz = Banco.rs1.getInt("viz"); // pegando os vizinhos
72

vertice = converterVertice2(viz);
S[cont2][vertice] = calc.getDistancia(Esquinas[cont2], viz);
}
}
Banco.rs1.close();
}
catch (Exception e){
System.out.println(e);
}
}

public void converterVertice(int e1, int e2) {


int v1 = 0, v2 = 0;
for (int cont = 0; cont < n; cont ++) {
if (Esquinas[cont] == e1) {
v1 = cont;
}
if (Esquinas[cont] == e2) {
v2 = cont;
}
}
d[v1][0] = 0;
gerarRota(v1, v2);
}

public int converterVertice2(int viz) {


int v1 = 0;
for (int cont = 0; cont < n; cont ++) {
if (Esquinas[cont] == viz)
v1 = cont;
}
return v1;
}

public void inicializarMatriz(){


for (int cont = 0; cont < n; cont++) {
d[cont][0] = 999; d[cont][1] = 0; Rota[cont] = -1;
for (int cont2 = 0; cont2 < n; cont2++) {
S[cont][cont2] = 999;
if (cont == cont2) {
S[cont][cont2] = 0;
}
}
}
}
}

Você também pode gostar