Commit 9bb3d3ae by Paffenholz, Andreas

### programs ch 15, Dijkstra

parent c31079ce
 /************************************* * Beispielprogramm zur Vorlesung * Einfuehrung in die Programmierung I * Andreas Paffenholz * TU Darmstadt, Wintersemester 2020/21 * (c) 2020- * * Kürzeste Wege in Netzwerken **************************************/ #include "dijkstra.h" void dijkstra (struct network * g, int start) { struct heap * h = init_heap(3, g->n_nodes); int * heap_index = (int *)malloc(g->n_nodes * sizeof(int)); for ( int i = 0; i < g->n_nodes; ++i) { heap_index[i] = 0; } push(h, heap_index, start, 0); g->nodes[start]->pred=-1; g->nodes[start]->dist=0; while (h->length) { int node_index = pop(h, heap_index); struct node * node = g->nodes[node_index]; node->visited = 1; for (int j = 0; j < node->n_outgoing_edges; j++) { struct edge * e = node->outgoing_edges[j]; struct node * neighbor = g->nodes[e->head]; if (!neighbor->visited && node->dist + e->weight <= neighbor->dist) { neighbor->pred = node_index; neighbor->dist = node->dist + e->weight; if ( heap_index[e->head] == 0 ) push(h, heap_index, e->head, neighbor->dist); else decrease_key(h, heap_index, e->head, neighbor->dist); } } } free(heap_index); free_heap(h); } void predecessors(struct network * g, int * pred) { for ( int i = 0; i < g->n_nodes; ++i ) { pred[i] = g->nodes[i]->pred; } }
 /************************************* * Beispielprogramm zur Vorlesung * Einfuehrung in die Programmierung I * Andreas Paffenholz * TU Darmstadt, Wintersemester 2020/21 * (c) 2020- * * Kürzeste Wege in Netzwerken, Header **************************************/ #ifndef DIJKSTRA_H #define DIJKSTRA_H #include "stdio.h" #include "stdlib.h" #include "limits.h" #include "network.h" #include "heap.h" void dijkstra (struct network *, int); void predecessors(struct network *, int *); #endif \ No newline at end of file
 /************************************* * Beispielprogramm zur Vorlesung * Einfuehrung in die Programmierung I * Andreas Paffenholz * TU Darmstadt, Wintersemester 2020/21 * (c) 2020- * * Kürzeste Wege in Netzwerken, Testprogramm * * Uebersetzen mit * gcc dijkstra_main.c dijkstra.c network.c heap.c -o dijkstra * Aufruf mit * ./dijkstra in_network 0 **************************************/ #include #include #include "network.h" #include "dijkstra.h" int main(int argc, char** argv) { if ( argc < 2 ) { fprintf(stderr, "Netwerk und Startknoten muessen angegeben werden\n"); exit(1); } char * infile = argv[1]; int start = atoi(argv[2]); struct network * g = read_network(infile); dijkstra(g,start); printf("The nodes have distance \n"); for ( int i = 0; i < g->n_nodes; ++i ) { printf("%d: %d\n", i, g->nodes[i]->dist); } int * pred = (int *)malloc(g->n_nodes * sizeof(int)); predecessors(g,pred); printf("The shortest path tree is given by the edges\n"); for ( int i = 0; i < g->n_nodes; ++i ) { if ( pred[i] != -1 ) { printf("(%d, %d)\n", pred[i],i); } } free(pred); free_network(g); return 0; } \ No newline at end of file
 /************************************* * Beispielprogramm zur Vorlesung * Einfuehrung in die Programmierung I * Andreas Paffenholz * TU Darmstadt, Wintersemester 2020/21 * (c) 2020- * * Priority Queue als Heap **************************************/ #include #include #include #include "heap.h" struct heap * init_heap (int n, int index_size) { struct heap * h = (struct heap *)malloc(sizeof (struct heap)); h->data = (int *)malloc((n+1) * sizeof (int)); h->key = (int *)malloc((n+1) * sizeof (int)); h->size = n; h->length = 0; return h; } void free_heap(struct heap * h) { free(h->data); free(h->key); free(h); } void resize_heap ( struct heap * h) { int new_size = h->size *3 / 2 >= h->length ? h->size *3 / 2 : h->size + 3; h->data = realloc(h->data, (new_size) * sizeof(int) ); h->key = realloc(h->key, (new_size) * sizeof(int) ); h->size = new_size; } void print_heap(struct heap * h) { printf("current heap (entries as (node, key)): "); for ( int i = 0; i < h->length; ++i) { printf("(%d, %d) ", h->data[i], h->key[i]); } printf("\n"); } int upheap ( struct heap * h, int * heap_index, int i, int key ) { int j = (i-1) / 2 ; while (i > 0) { if (h->key[j] < key) break; h->data[i] = h->data[j]; h->key[i] = h->key[j]; heap_index[h->data[i]] = i; i = j; j = (j-1) / 2; } return i; } void decrease_key (struct heap * h, int * heap_index, int node, int key ) { int insert_pos = upheap(h, heap_index, heap_index[node], key); h->data[insert_pos] = node; h->key[insert_pos ] = key; heap_index[node] = insert_pos; } void push (struct heap * h, int * heap_index, int node, int key ) { if ( h->size <= h->length ) resize_heap(h); int insert_pos = upheap(h, heap_index, h->length++, key); h->data[insert_pos] = node; h->key[insert_pos ] = key; heap_index[node] = insert_pos; } int min (struct heap * h, int i) { int lc = 2 * i + 1; int rc = 2 * i + 2; if (lc < h->length && h->key[lc] < h->key[h->length]) i = lc; if (rc < h->length && h->key[rc] < h->key[h->length]) i = rc; return i; } int downheap ( struct heap * h, int * heap_index, int i) { int j = min(h, i); if ( j != i ) { h->data[i] = h->data[j]; h->key[i] = h->key[j]; heap_index[h->data[i]] = i; j = downheap(h,heap_index, j); } return j; } int pop (struct heap * h, int * heap_index) { if ( h->length == 0 ) { return INT_MIN; } int node = h->data[0]; h->length--; int j = downheap(h,heap_index,0); h->data[j] = h->data[h->length]; h->key[j] = h->key[h->length]; heap_index[h->data[h->length]] = j; return node; } \ No newline at end of file
 /************************************* * Beispielprogramm zur Vorlesung * Einfuehrung in die Programmierung I * Andreas Paffenholz * TU Darmstadt, Wintersemester 2020/21 * (c) 2020- * * Priority Queue als Heap, Header **************************************/ #ifndef HEAP_H #define HEAP_H struct heap { int *data; int *key; int length; int size; }; struct heap * init_heap (int, int); void free_heap(struct heap *); void print_heap(struct heap * h); void push(struct heap *, int *, int, int); int pop(struct heap *, int *); void decrease_key (struct heap *, int *, int, int); #endif \ No newline at end of file
 8 0 1 7 0 2 4 0 3 10 1 3 2 1 4 5 1 6 2 2 0 6 2 1 2 2 6 7 3 4 1 3 7 2 4 1 2 4 5 3 6 2 2 6 4 4 6 5 5 7 4 2 7 5 1
 9 0 1 3 0 2 5 0 3 7 0 4 3 0 7 4 1 2 4 1 8 2 1 4 1 1 5 2 2 4 2 2 5 7 2 8 1 3 1 3 3 6 6 4 0 2 4 6 2 4 7 4 4 8 1 4 5 1 5 3 4 5 0 2 5 8 1 6 1 1 6 3 1 7 3 3 7 4 5 7 6 1 7 8 2 8 0 4