Commit | Line | Data |
---|---|---|
15d1825d BA |
1 | #include "sources/dijkstra.h" |
2 | #include <stdlib.h> | |
3 | #include "sources/utils/boolean.h" | |
4 | #include <math.h> | |
5 | ||
6 | // Dijkstra from index start : return vector of distances to every other vertex | |
7 | // TODO: use a good priority queue, and pass NI instead of pDistsIn (+ linear preprocessing) | |
8 | double* dijkstra_core(double* pDistsIn, int start, int n) { | |
9 | ||
10 | // initalisations | |
11 | double* pDistsOut = (double*)malloc(n*sizeof(double)); | |
12 | bool* visited = (bool*)malloc(n*sizeof(bool)); | |
13 | for (int i=0; i<n; i++) { | |
14 | pDistsOut[i] = INFINITY; | |
15 | visited[i] = S_FALSE; // nothing seen so far | |
16 | } | |
17 | pDistsOut[start] = 0.0; // we are at distance 0 from self | |
18 | ||
19 | while (S_TRUE) | |
20 | { | |
21 | double minGeodDist = INFINITY; | |
22 | ||
23 | // n1 <-- node in "unseen" with smallest geodesic distance | |
24 | // NOTE: on first loop, n1 == start | |
25 | int n1 = 0; | |
26 | for (int i=0; i<n; i++) | |
27 | { | |
28 | if (!visited[i] && pDistsOut[i] < minGeodDist) | |
29 | { | |
30 | n1 = i; | |
31 | minGeodDist = pDistsOut[i]; | |
32 | } | |
33 | } | |
34 | ||
35 | if (minGeodDist == INFINITY) | |
36 | break; // all is explored | |
37 | ||
38 | visited[n1] = S_TRUE; // n1 is expanded | |
39 | ||
40 | // For n2 running through neighbors of n1 | |
41 | for (int n2 = 0; n2<n; n2++) | |
42 | { | |
43 | int ind_n12 = n1*n+n2; // or n1+n*n2 (symmetry) | |
44 | if (!isnan(pDistsIn[ind_n12])) | |
45 | { | |
46 | // check if we'd better go through n1 (on the way from start to n2) | |
47 | if (pDistsOut[n2] > pDistsOut[n1] + pDistsIn[ind_n12]) | |
48 | pDistsOut[n2] = pDistsOut[n1] + pDistsIn[ind_n12]; | |
49 | } | |
50 | } | |
51 | } | |
52 | free(visited); | |
53 | ||
54 | return pDistsOut; | |
55 | } |