Escolar Documentos
Profissional Documentos
Cultura Documentos
nas
de Bellman visto em sala de aula, vale lembrar que pelo Principio da Otimalidade de
Bellman no necessariamente ser encontrada a melhor rota, pois por esse princpio
cada deciso tomada com base na deciso anterior, e nem sempre esse conjunto
de decises ser a melhor. Para que se encontre realmente a melhor rota possvel
entre uma cidade e outra deveramos construir um modelo baseado em
busca
INTRODUO
equilbrio entre elas pois so mantidas pelo Governo Federal, porm nas rodovias
estaduais e municipais pode-se encontrar um abismo ao se sair de um estado e
entrar em outro.
rpido, o sistema oferecer a opo de caminho mais rpido sendo que nesta opo
a variao de velocidade ser de acordo com o fluxo e/ou com o tipo de estrada
naquele percurso.
FORMULAO DO PROBLEMA
e recursos
ainda entrevista com um engenheiro do DNER que nos falou das dificuldades
existentes para o desenvolvimento de um projeto deste porte devido ao grande
nmero de variveis envolvidas, o que nos deixou ainda mais preocupados e atentos
para que abordassemos
desenvolvimento do modelo.
Desta
forma
ser
possvel
analisar
os
resultados,
e,
FORMULAO DO MODELO
TYPE
ESTRADA = RECORD
cidade : STRING[20];
proxima : STRING[20];
rodovia : STRING[5];
distancia : REAL;
veloci_media : REAL;
prox_no : INTEGER;
bifurca : INTEGER;
pontvolta : INTEGER;
END;
{FLUXOGRAMA}
CDIGO DO PROGRAMA
PROGRAM estradas;
USES CRT;
CONST
tamanho = 100;
TYPE
ESTRADA = RECORD
cidade : STRING[20];
proxima : STRING[20];
rodovia : STRING[5];
distancia : REAL;
veloci_media : REAL;
prox_no : INTEGER;
bifurca : INTEGER;
{esses campos}
pontvolta : INTEGER;
END;
STR20 = STRING[20];
VAR
{declarao de variveis}
ARQ_TESTE : TEXT;
PROCEDURE inicializa_var;
BEGIN
FOR i := 1 TO tamanho DO
BEGIN
parana[i].cidade := ' ;
parana[i].proxima := '';
parana[i].rodovia := '';
parana[i].distancia := 0;
parana[i].veloci_media := 0;
parana[i].prox_no := 0;
parana[i].bifurca := 0;
parana[i].pontvolta := 0;
END;
FOR i := 1 TO tamanho DO
pilha[i] := 0;
FOR i := 1 TO tamanho DO
rod_possiveis[i] := 0;
END;
percorrer
corretamente
PROCEDURE preenche_array;
BEGIN
ASSIGN(arq_est,'RODOVIAS.TXT');
RESET(arq_est);
todas
as
rvores
do
array.
n := 1;
WHILE NOT EOF(arq_est) DO
BEGIN
READLN(arq_est,cid,prox_cid,rod,dist1,velo);
VAL(dist1,dist,erro);
i := 1;
WHILE (parana[i].cidade <> '') AND (i <> tamanho) DO
BEGIN
IF parana[i].cidade = cid THEN
BEGIN
WHILE parana[i].bifurca <> 0 DO
i := parana[i].bifurca;
parana[i].bifurca := n;
parana[n].pontvolta := i;
i := tamanho;
END
ELSE
i := i + 1;
END;
parana[n].cidade := cid;
parana[n].proxima := prox_cid;
parana[n].rodovia := rod;
parana[n].distancia := dist;
parana[n].veloci_media := velo;
n := n + 1;
END;
CLOSE(arq_est);
n := 1;
WHILE (parana[n].cidade <> '') DO
BEGIN
i := 1;
WHILE (parana[i].cidade <> '') DO
BEGIN
IF (parana[i].proxima = parana[n].cidade) AND (parana[i].rodovia =
parana[n].rodovia) THEN
BEGIN
parana[i].prox_no := n;
i := tamanho;
END
ELSE
i := i + 1;
END;
n := n + 1;
END;
n := 1;
WHILE (parana[n].cidade <> '') DO
BEGIN
i := 1;
WHILE (parana[i].cidade <> '') DO
BEGIN
IF (parana[i].proxima = parana[n].cidade) AND (parana[i].prox_no = 0) THEN
parana[i].prox_no := n;
i := i + 1;
END;
n := n + 1;
END;
END;
BEGIN
FOR i := 1 TO tamanho DO
IF parana[i].cidade = origdest THEN
BEGIN
aux := i;
procura_cidade := aux;
i := tamanho;
END;
IF parana[aux].cidade <> origdest THEN
procura_cidade := 0;
END;
END;
PROCEDURE desempilha;
BEGIN
FOR i := 1 to tamanho-1 DO
pilha[i] := pilha[i+1];
END;
{ Essa funo serve para voltar para a primeira bifurcao da cidade que foi passada
como parmetro, a funo retornar a posio no array da primeira bifurcao dessa
cidade, para isso usa o ponteiro "pontvolta" que armazena a posio da bifurcao
anterior, a funo fica em loop at chegar na primeira bifurcao da cidade.
}
{ Essa funo verifica se o destino em que se quer chegar possvel, devo dizer que
como esse programa funciona sobre o Principio da Otimalidade de Bellman o que
"destino" vira "origem" e vice-versa. Essa funo pesquisa toda a rvore B a partir da
origem que foi passada como parmetro, e verifica se o destino passado como
parmetro possvel, caso seja, ento a funo retornar TRUE, seno retornar
FALSE. Como essa funo chamada vrias vezes at completar a rota, o retorno
de TRUE e FALSE s se faz necessrio na primeira chamada, a partir da primeira
chamada, se ela for acionada novamente ela sempre retornar TRUE, visto que se
ela foi acionada novamente porque da primeira vez ela retornou TRUE, logo o
destino possvel. Considerando que no primeiro acionamento dessa funo ela
retornou TRUE ento o array "rod_possiveis" receber todas as bifurcaes
possveis da cidade atual que permitem chegar ao destino especificado, a
"PROCEDURE melhor_caminho"
chegar
ao
destino
especificado.
rod_possiveis[n] := pilha[1];
n := n + 1;
IF parana[pilha[1]].bifurca <> 0 THEN
BEGIN
x := parana[pilha[1]].bifurca;
desempilha;
empilha(x);
END
ELSE
desempilha;
END
ELSE
BEGIN
IF parana[x].prox_no = 0 THEN
BEGIN
desempilha;
x := pilha[1];
WHILE (parana[x].bifurca = 0) AND (pilha[1] <> 0) DO
BEGIN
desempilha;
x := pilha[1];
END;
IF pilha[1] = 0 THEN
procura_destino := FALSE
ELSE
BEGIN
x := parana[x].bifurca;
desempilha;
empilha(x);
END;
END
ELSE
BEGIN
x := parana[x].prox_no;
x := volta_primeiro_no(x);
empilha(x);
END;
END;
END;
IF rod_possiveis[1] <> 0 THEN
procura_destino := TRUE;
END;
- Kilometragem total;
- Tempo aproximado de percurso;
- Combustvel necessrio para se fazer a viagem;
- Quantidade em dinheiro necessria para pagar a gasolina;
Feito isso o controle do programa voltar ao programa principal que perguntar ao
usurio se ele deseja continuar ou deseja sair do programa.
PROCEDURE melhor_caminho;
VAR
z,k :INTEGER;
total : REAL;
tempo,tot_litros,tot_dinheiro : REAL;
tempo1 : INTEGER;
BEGIN
total := 0;
tempo := 0;
FOR i := 1 TO tamanho DO
rota[i] := 0;
posic_origem := volta_primeiro_no(posic_origem);
encontrei := procura_destino(destino,posic_origem);
k := 1;
IF encontrei = TRUE THEN
BEGIN
WHILE encontrei = TRUE DO
BEGIN
rota[k] := rod_possiveis[1];
z := 2;
WHILE rod_possiveis[z] <> 0 DO
BEGIN
DISTANCIA
FOR i := k DOWNTO 1 DO
BEGIN
WRITE(parana[rota[i]].proxima,' --> ',parana[rota[i]].cidade,' '
,parana[rota[i]].distancia:6:2,' Km',' ',parana[rota[i]].rodovia);
IF parana[rota[i]].veloci_media < 100 THEN
WRITE('
')
RODOVIA');
ELSE
WRITE(' ');
WRITELN(parana[rota[i]].veloci_media:5:2,' Km/h');
END;
encontrei := FALSE;
WRITELN('
tempo1 := 0;
WHILE tempo >= 60 DO
BEGIN
tempo := tempo - 60;
tempo1 := tempo1 + 1;
END;
WRITE('TEMPO APROXIMADO DE PERCURSO = ');
IF tempo1 = 0 THEN
WRITELN(tempo:2:0,' minuto(s)')
ELSE IF tempo = 0 THEN
WRITELN(tempo1,' hora(s)')
ELSE
WRITELN(tempo1,' hora(s) e ',tempo:2:0,' minuto(s)');
tot_litros := total / consumo;
tot_dinheiro := tot_litros * combustivel;
WRITELN('COMBUSTIVEL NECESSARIO: ',tot_litros:6:2, ' litro(s)', '
QUANTIA NECESSARIA: R$',tot_dinheiro:7:2);
total := 0;
END
ELSE
BEGIN
posic_origem := volta_primeiro_no(parana[rota[k]].prox_no);
encontrei := procura_destino(destino,posic_origem);
END;
k := k + 1;
END;
END
ELSE
WRITELN('NO POSSVEL CHEGAR EM ',origem,' SAINDO DE ',destino);
END;
{ Esse procedimento serve somente para que o usurio informe a cidade de origem e
a cidade de destino, a varivel "destino" receber a origem que o usurio informou e
a varivel "origem" receber o destino que o usurio informou, isso se deve ao fato
de que o programa faz a pesquisa de trs para frente. Esse procedimento acionado
em dois casos:
1 Quando se quer mudar a velocidade entre duas cidades;
2 Quando se vai informar a cidade origem e a cidade destino da pesquisa a ser
efetuada;
A mensagem que passada como parmetro apenas para diferenciar quando se
est no primeiro ou no segundo caso;
PROCEDURE opcoes;
VAR
muda_vel : CHAR;
achei : BOOLEAN;
velo1 : STRING;
velo2 : REAL;
cont_vel : INTEGER;
rod1 : STRING[5];
BEGIN
minimizar := 'D';
REPEAT
CLRSCR;
WRITE('DESEJA MINIMIZAR TEMPO OU DISTANCIA (T/D): ');
READLN(minimizar);
UNTIL (UPCASE(minimizar) = 'T') OR (UPCASE(minimizar) = 'D');
IF UPCASE(minimizar) = 'T' THEN
BEGIN
REPEAT
CLRSCR;
WRITE('DESEJA ALTERAR A VELOCIDADE MEDIA DE ALGUMA
RODOVIA (S/N): ');
READLN(muda_vel);
UNTIL (UPCASE(muda_vel) = 'S') OR (UPCASE(muda_vel) = 'N');
IF UPCASE(muda_vel) = 'S' THEN
BEGIN
REPEAT
achei := FALSE;
entra_cidades('');
FOR i := 1 TO tamanho DO
IF (parana[i].cidade = origem) AND (parana[i].proxima = destino) THEN
BEGIN
achei := TRUE;
rod1 := parana[i].rodovia;
i := tamanho;
END
encerrado.
BEGIN
inicializa_var;
preenche_array;
grava_alteracoes := FALSE;
REPEAT
CLRSCR;
WRITE('ENTRE COM O CONSUMO MEDIO DO VEICULO (Km/l): ');
READLN(consumo1);
VAL(consumo1,consumo,conf_consumo);
WRITE('ENTRE COM O VALOR EM R$ DO COMBUSTIVEL (999.99): ');
READLN(combustivel1);
VAL(combustivel1,combustivel,conf_comb);
IF conf_consumo <> 0 THEN
WRITELN('VALOR CONSUMO INCORRETO - DEVE INFORMAR NUMERO
REAL DE 5 CASAS NO MXIMO');
IF conf_comb <> 0 THEN
WRITELN('VALOR PRECO INCORRETO - DEVE INFORMAR NUMERO
REAL DE 5 CASAS NO MXIMO');
IF (conf_consumo <> 0) OR (conf_comb <> 0) THEN
BEGIN
WRITE('PRESSIONE ENTER PARA CONTINUAR');
READLN;
END;
UNTIL (conf_consumo = 0) AND (conf_comb = 0);
REPEAT
CLRSCR;
opcoes;
final := 'S';
entra_cidades('DIGITE AS CIDADES QUE SERO UTILIZADAS PARA A
PESQUISA');
posic_origem := procura_cidade(origem);
posic_destino := procura_cidade(destino);
CLRSCR;
WRITE('DESEJA SALVAR EM DISCO AS ALTERACOES DE VELOCIDADE
(S/N): ');
READLN(final);
UNTIL (UPCASE(final) = 'S') OR (UPCASE(final) = 'N');
IF UPCASE(final) = 'S' THEN
BEGIN
ASSIGN(arq_est,'RODOVIAS.TXT');
REWRITE(arq_est);
FOR i := 1 TO tamanho DO
BEGIN
STR(parana[i].distancia:7:1,dist1);
IF parana[i].cidade <> '' THEN
WRITELN(arq_est,parana[i].cidade, parana[i].proxima,
parana[i].rodovia,dist1,parana[i].veloci_media:5:2);
END;
CLOSE(arq_est);
END;
END;
END.
{ Fim do Programa }
ESTIMATIVA DE PARMETROS
VARIVEIS DE ENTRADA
VARIVEIS DE SADA
Nota2: As sadas do sistema estaro dispostas no sentido real que OESTE =>
LESTE, porm a pesquisa do melhor caminho feita no sentido LESTE => OESTE,
esse tratamento transparente para o usurio, no entanto nas explicaes que
daremos a seguir utilizaremos a metodologia do programa, ou seja, LESTE =>
OESTE.
DISTANCIA RODOVIA
VELOCIDADE
FOZ DO IGUACU
97.00 Km
BR277
80.00 Km/h
CEU AZUL
--> CASCAVEL
48.00 Km
BR277
80.00 Km/h
CASCAVEL
BR277
80.00 Km/h
55.00 Km
BR277
80.00 Km/h
TRES PINHEIROS
--> GUARAPUAVA
55.00 Km
BR277
80.00 Km/h
GUARAPUAVA
--> RELOGIO
45.00 Km
BR277
80.00 Km/h
RELOGIO
138.00 Km
BR277
80.00 Km/h
OSORIO SANTOS
18.00 Km
BR277
80.00 Km/h
24.00 Km
BR376
80.00 Km/h
CAMPO LARGO
--> ARAUCARIA
26.00 Km
PR423
80.00 Km/h
ARAUCARIA
--> CURITIBA
9.00 Km
PR421
80.00 Km/h
TOTAL =
643.00 Km
47.63 litro(s)
2 minuto(s)
QUANTIA NECESSARIA: R$
28.10
DISTANCIA RODOVIA
VELOCIDADE
FOZ DO IGUACU
97.00 Km
BR277
80.00 Km/h
CEU AZUL
--> CASCAVEL
48.00 Km
BR277
80.00 Km/h
CASCAVEL
168.00 Km
BR369
80.00 Km/h
CAMPO MOURAO
--> IRETAMA
56.00 Km
BR487
80.00 Km/h
IRETAMA
20.00 Km
PR487
80.00 Km/h
BELA VISTA
--> PITANGA
31.00 Km
PR460
80.00 Km/h
PITANGA
--> GUARAPUAVA
84.00 Km
PR466
140.00 Km/h
GUARAPUAVA
--> RELOGIO
45.00 Km
BR277
80.00 Km/h
RELOGIO
138.00 Km
BR277
80.00 Km/h
OSORIO SANTOS
18.00 Km
BR277
80.00 Km/h
24.00 Km
BR376
80.00 Km/h
CAMPO LARGO
--> ARAUCARIA
26.00 Km
PR423
80.00 Km/h
ARAUCARIA
--> CURITIBA
9.00 Km
PR421
80.00 Km/h
TOTAL =
764.00 Km
56.59 litro(s)
6 minuto(s)
QUANTIA NECESSARIA: R$
33.39
DISTANCIA RODOVIA
VELOCIDADE
IMBAU
90.00 Km
BR376
80.00 Km/h
CONCHAS VELHAS
--> PIRIQUITOS
11.00 Km
BR373
80.00 Km/h
PIRIQUITOS
-->
38.00 Km
PR151
80.00 Km/h
CASTRO
TOTAL =
139.00 Km
10.30 litro(s)
QUANTIA NECESSARIA: R$
6.07
DISTANCIA RODOVIA
-->
TIBAGI
48.00 Km
PR340
VELOCIDADE
80.00 Km/h
TIBAGI
-->
CASTRO
60.00 Km
TOTAL =
8.00 litro(s)
130.00 Km/h
108.00 Km
PR340
4 minuto(s)
QUANTIA NECESSARIA: R$
4.72
CONCLUSO