-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathDijkstra.c
160 lines (133 loc) · 3.81 KB
/
Dijkstra.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
Algoritmo de Dijkstra
Fernando Emilio Puntel
Programa de Pós-Graduação em Informática
Universidade Federal de Santa Maria
Maio/2017
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
// Total de cidades para construção do grafo
#define TOTALCIDADES 20
// Grafo de distancia entre as cidades
int distancias[TOTALCIDADES*TOTALCIDADES];
double custos[TOTALCIDADES];
/*
Funcao criaGrafo
- Rand para o total de ligacoes que o grafo irá ter
- Rand para qual cidade origem e destino
- Verifica se nao eh a mesma cidade e se ja nao possui ligacao entre as mesmas
- Rand para a distância
- Vetor distancias:
- Pos 0 ate (TOTALCIDADES - 1) = cidade 1
- Pos (TOTALCIDADES) ate ((2*TOTALCIDADES) -1) = cidade 2
*/
void criaGrafo(){
int origem, destino, totalLigacoes, i, ok, distancia;
totalLigacoes = rand() % (TOTALCIDADES * 4);
printf("TOTAL LIGACOES: %i\n", totalLigacoes);
for(i = 0; i < totalLigacoes; i++){
ok = 0;
while (ok == 0){
origem = rand() % TOTALCIDADES;
destino = rand() % TOTALCIDADES;
if (origem != destino){
if (distancias[(origem) * TOTALCIDADES + destino] == -1){
distancia = (rand() % 20) + 1;
distancias[(origem) * TOTALCIDADES + destino] = distancia;
ok = 1;
printf ("Ligacao entre as cidades: %i e %i com distancia: %i\n", origem, destino, distancia);
}
}
}
}
}
/*
Funcao menorCaminho
- Recebe a origem e destino para calculo
- Aloca vetor necessário
- Verifica as ligacoes que direta que a "cidade" possui
- Por fim, é feito o calculo do menor caminho
- Impresso o resultado
*/
void dijkstra(int origem, int destino){
int *anterior, i, aux;
int *verticesNoCaminho, calculo; // Vertices que sao acessados para o menor caminho
double distMinima, auxDist; // Custoo com os caminhos
verticesNoCaminho = calloc (TOTALCIDADES, sizeof (int *));
if (verticesNoCaminho == NULL){
printf("ERROR: Erro na alocacao \n");
printf("ERROR: Erro na alocacao \n");
exit(-1);
}
for (i = 0; i < TOTALCIDADES; i++){
verticesNoCaminho[i] = 0;
if (distancias[(origem) * TOTALCIDADES + i] != -1){
custos[i] = distancias[(origem) * TOTALCIDADES + i];
}else{
custos[i] = HUGE_VAL;
}
}
verticesNoCaminho[origem] = 1;
custos[origem] = 0;
// Principal laço
do{
distMinima = HUGE_VAL;
for(i = 0; i < TOTALCIDADES; i++){
if (!verticesNoCaminho[i]){
if (custos[i] >= 0 && custos[i] < distMinima){
distMinima = custos[i];
aux = i;
}
}
}
if (distMinima != HUGE_VAL && aux != destino){
verticesNoCaminho[aux] = 1;
for(i = 0; i < TOTALCIDADES; i++){
if (!verticesNoCaminho[i]){
if (distancias[aux * TOTALCIDADES + i] != -1 && custos[aux] + distancias[aux * TOTALCIDADES + i] < custos[i]){
custos[i] = custos[aux] + distancias[aux * TOTALCIDADES + i];
}
}
}
}
}while (aux != destino && distMinima != HUGE_VAL);
/*IMPRIME RESULTADO*/
printf("Distancia de %i ate %i: ", origem, destino);
printf("Custo: %f\n", custos[destino]);
}
/*
Funcao calculoDistancia
- Dois for's que chamam a funcao para calculo do menor caminho
*/
void calculoDistancia(){
int i, j;
for(i = 0; i < TOTALCIDADES; i++){
for(j = 0; j < TOTALCIDADES; j++){
dijkstra(i, j);
}
}
}
/*
Todas as distancias e custos sao zeradas, pois na hora do algoritmo eh verificado
as cidades que tem ligacoes.
*/
void zeraDistancia(){
int i;
for(i = 0; i < TOTALCIDADES * TOTALCIDADES; i++){
distancias[i] = -1;
}
/* Zera custos*/
for(i = 0; i < TOTALCIDADES; i++){
custos[i] = 0;
}
}
int main(){
srand((unsigned)TOTALCIDADES);
zeraDistancia();
criaGrafo();
calculoDistancia();
return 0;
}