/** * Shortest Path solution implemented using the Dijkstra algorithm */ int dijkstra(Graph *graph, int source, pri_queue priq, Energy *distance, int previous[], Energy shortest_distance) { int vertex, adjacent, v; Energy alt; int *visited = calloc(graph->list_size, sizeof(int)); for(v = 0; v < graph->list_size; distance[v++] = ENERGY_MAX); previous[source] = NONE; distance[source] = graph->vertexes[source].pixel->energy; visited[source] = 1; priq_purge(priq); priq_push(priq, source, distance[source]); int dest = NONE; while(priq_size(priq)) { vertex = priq_pop(priq); v = 0; adjacent = graph->vertexes[vertex].adj[v++]; if(adjacent == NONE) { dest = vertex; break; } #ifdef OPT_GRAPH_SHORTEST_PATH_BREAK else if (distance[vertex] >= shortest_distance) { dest = BREAK; break; } #endif do { if(adjacent >= 0 && !visited[adjacent]) { alt = distance[vertex] + graph->vertexes[adjacent].pixel->energy; if(alt < distance[adjacent]) { distance[adjacent] = alt; previous[adjacent] = vertex; priq_push(priq, adjacent, alt); } } adjacent = graph->vertexes[vertex].adj[v++]; } while(adjacent != NONE); visited[vertex] = 1; } free(visited); return dest; }
int main() { int i, p; const char *c, *tasks[] ={ "Clear drains", "Feed cat", "Make tea", "Solve RC tasks", "Tax return" }; int pri[] = { 3, 4, 5, 1, 2 }; /* make two queues */ pri_queue q = priq_new(0), q2 = priq_new(0); /* push all 5 tasks into q */ for (i = 0; i < 5; i++) priq_push(q, tasks[i], pri[i]); /* pop them and print one by one */ while ((c = priq_pop(q, &p))) printf("%d: %s\n", p, c); /* put a million random tasks in each queue */ for (i = 0; i < 1 << 20; i++) { p = rand() / ( RAND_MAX / 5 ); priq_push(q, tasks[p], pri[p]); p = rand() / ( RAND_MAX / 5 ); priq_push(q2, tasks[p], pri[p]); } printf("\nq has %d items, q2 has %d items\n", priq_size(q), priq_size(q2)); /* merge q2 into q; q2 is empty */ priq_combine(q, q2); printf("After merge, q has %d items, q2 has %d items\n", priq_size(q), priq_size(q2)); /* pop q until it's empty */ for (i = 0; (c = priq_pop(q, 0)); i++); printf("Popped %d items out of q\n", i); return 0; }
/** * Priority queue invariant check. * Complexity always O(2n) * @return If NULL -> Ok. Else an error msg. */ const char* priq_invariant(Priq q) { if(!q) return "NULL POINTER EXCEP: Pcue base struct undefinded"; if(!q->cmp) return "NULL POINTER EXCEP: Pcue compare function undefinded"; if(!q->top && priq_size(q) != 0) return "WRONG STRUCTURE: top = NULL but size > 0"; if(q->top && priq_size(q) == 0) return "WRONG STRUCTURE: top != NULL but size = 0"; if(!_priq_heap_inv(q->top, q->cmp)) return "WRONG STRUCTURE: heap invariant failed"; if(q->size != _priq_count_contend(q->top)) return "WRONG STRUCTURE: size != real #contend"; return NULL; }