Dijkstra's algorithm: Difference between revisions
Content added Content deleted
m (→{{header|C}}: unused vars) |
(→{{header|C}}: buthered the program so it runs faster for large graph) |
||
Line 58: | Line 58: | ||
#include <stdlib.h> |
#include <stdlib.h> |
||
#include <string.h> |
#include <string.h> |
||
⚫ | |||
typedef struct node_t node_t, *heap_t; |
typedef struct node_t node_t, *heap_t; |
||
typedef struct edge_t edge_t; |
typedef struct edge_t edge_t; |
||
struct edge_t { |
struct edge_t { |
||
node_t *nd; |
node_t *nd; /* target of this edge */ |
||
edge_t *sibling; |
edge_t *sibling;/* for singly linked list */ |
||
int len; |
int len; /* edge cost */ |
||
}; |
}; |
||
struct node_t { |
struct node_t { |
||
edge_t *edge; /* singly linked list of edges */ |
edge_t *edge; /* singly linked list of edges */ |
||
node_t *via; /* where previous node is in shortest path */ |
node_t *via; /* where previous node is in shortest path */ |
||
double dist; |
double dist; /* distance from origining node */ |
||
char name[8]; |
char name[8]; /* the, er, name */ |
||
int heap_idx; /* link to heap position for updating distance */ |
int heap_idx; /* link to heap position for updating distance */ |
||
}; |
}; |
||
/* --- edge management --- */ |
|||
#ifdef BIG_EXAMPLE |
|||
# define BLOCK_SIZE (1024 * 32 - 1) |
|||
#else |
|||
# define BLOCK_SIZE 15 |
|||
#endif |
|||
edge_t *edge_root = 0, *e_next = 0; |
|||
/* Don't mind the memory management stuff, they are besides the point. |
|||
⚫ | |||
⚫ | |||
⚫ | |||
if (e_next == edge_root) { |
|||
edge_root = malloc(sizeof(edge_t) * (BLOCK_SIZE + 1)); |
|||
edge_root[BLOCK_SIZE].sibling = e_next; |
|||
e_next = edge_root + BLOCK_SIZE; |
|||
⚫ | |||
--e_next; |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
for (; edge_root; edge_root = e_next) { |
|||
e_next = edge_root[BLOCK_SIZE].sibling; |
|||
⚫ | |||
⚫ | |||
} |
|||
/* --- priority queue stuff --- */ |
|||
heap_t *heap; |
heap_t *heap; |
||
int heap_len; |
int heap_len; |
||
Line 84: | Line 121: | ||
if (nd->via && d >= nd->dist) return; |
if (nd->via && d >= nd->dist) return; |
||
/* find existing or create |
/* find existing heap entry, or create a new one */ |
||
nd->dist = d; |
nd->dist = d; |
||
nd->via = via; |
nd->via = via; |
||
i = nd->heap_idx; |
|||
if (!i) i = ++heap_len; |
|||
/* upheap */ |
/* upheap */ |
||
Line 123: | Line 160: | ||
} |
} |
||
/* --- Dijkstra stuff; unreachable nodes will never make into the queue --- */ |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
void calc_all(node_t *start) |
void calc_all(node_t *start) |
||
{ |
{ |
||
Line 155: | Line 184: | ||
} |
} |
||
⚫ | |||
⚫ | |||
edge_t *e, *tmp; |
|||
for (e = nd->edge; e; e = tmp) { |
|||
tmp = e->sibling; |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
int main(void) |
int main(void) |
||
{ |
{ |
||
Line 186: | Line 204: | ||
int i, j, c; |
int i, j, c; |
||
# define N_NODES |
# define N_NODES 4000 |
||
node_t *nodes = calloc(sizeof(node_t), N_NODES); |
node_t *nodes = calloc(sizeof(node_t), N_NODES); |
||
Line 197: | Line 215: | ||
for (i = 0; i < N_NODES; i++) { |
for (i = 0; i < N_NODES; i++) { |
||
for (j = 0; j < N_NODES; j++) { |
for (j = 0; j < N_NODES; j++) { |
||
/* majority of runtime is actually spent here */ |
|||
if (i == j) continue; |
if (i == j) continue; |
||
c = rand() % 100; |
c = rand() % 100; |
||
Line 214: | Line 233: | ||
} |
} |
||
#if 0 |
|||
/* |
|||
/* real programmers don't free memories (they use Fortran) */ |
|||
for (i = 0; i < N_NODES; i++) |
|||
free_edges(); |
|||
free(heap); |
free(heap); |
||
free(nodes); |
free(nodes); |
||
#endif |
|||
*/ |
|||
return 0; |
return 0; |
||
}</lang>output<pre> |
}</lang>output<pre> |