int dfs(Graph * graph, List * ordered) { DfsVertex *vertex; ListElmt *element; /***************************************************************************** * * * Initialize all of the vertices in the graph. * * * *****************************************************************************/ for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { vertex = ((AdjList *) list_data(element))->vertex; vertex->color = white; } /***************************************************************************** * * * Perform depth-first search. * * * *****************************************************************************/ list_init(ordered, NULL); for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { /************************************************************************** * * * Ensure that every component of unconnected graphs is searched. * * * **************************************************************************/ vertex = ((AdjList *) list_data(element))->vertex; if (vertex->color == white) { if (dfs_main (graph, (AdjList *) list_data(element), ordered) != 0) { list_destroy(ordered); return -1; } } } return 0; }
static void print_graph_pth(const Graph *graph) { Set *adjacent; PathVertex *vertex; ListElmt *element, *member; int i, j; /***************************************************************************** * * * Display the graph for computing shortest paths. * * * *****************************************************************************/ fprintf(stdout, "Vertices=%d, edges=%d\n", graph_vcount(graph), graph_ecount(graph)); i = 0; element = list_head(&graph_adjlists(graph)); while (i < list_size(&graph_adjlists(graph))) { vertex = ((AdjList *) list_data(element))->vertex; fprintf(stdout, "graph[%03d]=%s: ", i, (char *) vertex->data); j = 0; adjacent = &((AdjList *) list_data(element))->adjacent; member = list_head(adjacent); while (j < set_size(adjacent)) { vertex = list_data(member); if (j > 0) fprintf(stdout, ", "); fprintf(stdout, "%s(%4.1lf)", (char *) vertex->data, vertex->weight); member = list_next(member); j++; } i++; fprintf(stdout, "\n"); element = list_next(element); } return; }
static void print_graph(const Graph *graph) { Set *adjacent; ListElmt *element, *member; int i, j; /***************************************************************************** * * * Display the graph. * * * *****************************************************************************/ fprintf(stdout, "Vertices=%d, edges=%d\n", graph_vcount(graph), graph_ecount (graph)); i = 0; element = list_head(&graph_adjlists(graph)); while (i < list_size(&graph_adjlists(graph))) { fprintf(stdout, "graph[%03d]=%s: ", i, (char *)((AdjList *)list_data( element))->vertex); j = 0; adjacent = &((AdjList *)list_data(element))->adjacent; member = list_head(adjacent); while (j < set_size(adjacent)) { if (j > 0) fprintf(stdout, ", "); fprintf(stdout, "%s", (char *)list_data(member)); member = list_next(member); j++; } i++; fprintf(stdout, "\n"); element = list_next(element); } return; }
int shortest(Graph *graph, const PathVertex *start, List *paths, int (*match) (const void *key1, const void *key2)){ AdjList *adjlist; PathVertex *pth_vertex, *adj_vertex; ListElmt *element, *member; double minimum; int found, i; //Initialize all of the vertices in the graph. found = 0; for (element=list_head(&graph_adjlists(graph)); element != NULL; element=list_next(element)){ pth_vertex = ((AdjList*) list_data(element))->vertex; if(match(pth_vertex, start)){ //Initialize the start vertex. pth_vertex->color = white; pth_vertex->d = 0; pth_vertex->parent = NULL; found = 1; }else { //Initialize vertices other than the start vertex. pth_vertex->color = white; pth_vertex-d = DBL_MAX; pth_vertex->parent = NULL; } //Return if the start vertex was not found. if(!found) return -1; //Use Dijkstar's algorithm to compute shortest from the start vertex. i = 0; } }
/* mst */ int mst(Graph *graph, const MstVertex *start, List *span, int (*match)(const void *key1, const void *key2)) { AdjList *adjlist; MstVertex *mst_vertex, *adj_vertex; ListElmt *element, *member; double minimum; int found, i; /* Initialize all of the vertices in the graph. */ found = 0; for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { mst_vertex = ((AdjList *)list_data(element))->vertex; if (match(mst_vertex, start)) { /* Initialize the start vertex. */ mst_vertex->color = white; mst_vertex->key = 0; mst_vertex->parent = NULL; found = 1; } else { /* Initialize vertices other than the start vertex. */ mst_vertex->color = white; mst_vertex->key = DBL_MAX; mst_vertex->parent = NULL; } } /* Return if the start vertex was not found. */ if (!found) { return -1; } /* Use Prim's algorithm to compute a minimum spanning tree. */ i = 0; while (i < graph_vcount(graph)) { /* Select the white vertex with the smallest key value. */ minimum = DBL_MAX; for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { mst_vertex = ((AdjList *)list_data(element))->vertex; if (mst_vertex->color == white && mst_vertex->key < minimum) { minimum = mst_vertex->key; adjlist = list_data(element); } } /* color the selected vertex black. */ ((MstVertex *)adjlist->vertex)->color = black; /* traverse each vertex adjacent to the selected vertex. */ for (member = list_head(&adjlist->adjacent); member != NULL; member = list_next(member)) { adj_vertex = list_data(member); /* Find the adjacent vertex in the list of * adjacency-list structures. */ for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { mst_vertex = ((AdjList *) list_data(element))->vertex; if (match(mst_vertex, adj_vertex)) { /* decide whether to change the key * value and parent of the adjacent * vertex in the list of * adjacency-list structures.*/ if (mst_vertex->color == white && adj_vertex->weight < mst_vertex->key) { mst_vertex->key = adj_vertex->weight; mst_vertex->parent = adjlist->vertex; } break; } } } /* prepare to select the next vertex. */ i++; } /* Load the minimum spanning tree into a list. */ list_init(span, NULL); for (element = list_head(&graph_adjlists(graph)); element != NULL ; element = list_next(element)) { /* Load each black vertex from the list of * adjacency-list structures. */ mst_vertex = ((AdjList *)list_data(element))->vertex; if (mst_vertex->color == black) { if (list_ins_next(span, list_tail(span), mst_vertex) != 0) { list_destroy(span); return -1; } } } return 0; }
int mst(Graph *graph, const MstVertex *start, List *span, int (*match)(const void *key1, const void *key2)) { AdjList *adjlist = NULL; MstVertex *mst_vertex, *adj_vertex; ListElmt *element, *member; double minimum; int found, i; found = 0; for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { mst_vertex = ((AdjList *)list_data(element))->vertex; if (match(mst_vertex, start)) { mst_vertex->color = white; mst_vertex->key = 0; mst_vertex->parent = NULL; found = 1; } else { mst_vertex->color = white; mst_vertex->key = DBL_MAX; mst_vertex->parent = NULL; } } if (!found) return -1; /* * Use Prim's algorithm */ i = 0; /* Select white vertex with the smallest value */ while (i < graph_vcount(graph)) { minimum = DBL_MAX; for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { mst_vertex = ((AdjList *)list_data(element))->vertex; if (mst_vertex->color == white && mst_vertex->key < minimum) { minimum = mst_vertex->key; adjlist = list_data(element); } } /* Color the selected vertex black */ ((MstVertex *)adjlist->vertex)->color = black; for (member = list_head(&adjlist->adjacent); member != NULL; member = list_next(member)) { adj_vertex = list_data(member); for(element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { mst_vertex = ((AdjList *)list_data(element))->vertex; if (match(mst_vertex, adj_vertex)) { if (mst_vertex->color == white && adj_vertex->weight < mst_vertex->key) { mst_vertex->key = adj_vertex->weight; mst_vertex->parent = adjlist->vertex; } break; } } } i++; } list_init(span, NULL); for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { mst_vertex = ((AdjList *)list_data(element))->vertex; if (mst_vertex->color == black) { if (list_ins_next(span, list_tail(span), mst_vertex) != 0) { list_destroy(span); return -1; } } } return 0; }
int bfs(Graph *graph, BfsVertex *start, List *hops) { Queue queue; AdjList *adjlist, *clr_adjlist; BfsVertex *clr_vertex, *adj_vertex; ListElmt *element, *member; /***************************************************************************** * * * Initialize all of the vertices in the graph. * * * *****************************************************************************/ for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { clr_vertex = ((AdjList *)list_data(element))->vertex; if (graph->match(clr_vertex, start)) { /*********************************************************************** * * * Initialize the start vertex. * * * ***********************************************************************/ clr_vertex->color = gray; clr_vertex->hops = 0; } else { /*********************************************************************** * * * Initialize vertices other than the start vertex. * * * ***********************************************************************/ clr_vertex->color = white; clr_vertex->hops = -1; } } /***************************************************************************** * * * Initialize the queue with the adjacency list of the start vertex. * * * *****************************************************************************/ queue_init(&queue, NULL); if (graph_adjlist(graph, start, &clr_adjlist) != 0) { queue_destroy(&queue); return -1; } if (queue_enqueue(&queue, clr_adjlist) != 0) { queue_destroy(&queue); return -1; } /***************************************************************************** * * * Perform breadth-first search. * * * *****************************************************************************/ while (queue_size(&queue) > 0) { adjlist = queue_peek(&queue); /************************************************************************** * * * Traverse each vertex in the current adjacency list. * * * **************************************************************************/ for (member = list_head(&adjlist->adjacent); member != NULL; member = list_next(member)) { adj_vertex = list_data(member); /*********************************************************************** * * * Determine the color of the next adjacent vertex. * * * ***********************************************************************/ if (graph_adjlist(graph, adj_vertex, &clr_adjlist) != 0) { queue_destroy(&queue); return -1; } clr_vertex = clr_adjlist->vertex; /*********************************************************************** * * * Color each white vertex gray and enqueue its adjacency list. * * * ***********************************************************************/ if (clr_vertex->color == white) { clr_vertex->color = gray; clr_vertex->hops = ((BfsVertex *)adjlist->vertex)->hops + 1; if (queue_enqueue(&queue, clr_adjlist) != 0) { queue_destroy(&queue); return -1; } } } /************************************************************************** * * * Dequeue the current adjacency list and color its vertex black. * * * **************************************************************************/ if (queue_dequeue(&queue, (void **)&adjlist) == 0) { ((BfsVertex *)adjlist->vertex)->color = black; } else { queue_destroy(&queue); return -1; } } queue_destroy(&queue); /***************************************************************************** * * * Pass back the hop count for each vertex in a list. * * * *****************************************************************************/ list_init(hops, NULL); for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { /************************************************************************** * * * Skip vertices that were not visited (those with hop counts of -1). * * * **************************************************************************/ clr_vertex = ((AdjList *)list_data(element))->vertex; if (clr_vertex->hops != -1) { if (list_ins_next(hops, list_tail(hops), clr_vertex) != 0) { list_destroy(hops); return -1; } } } return 0; }
/*--------------------------------------------------------------*/ int shortest(Graph *graph, Heap *H, double *A_weights, const PathVertex *start, List *paths, int (*match) (const void *key1, const void *key2), int gw, int gh) { AdjList *adjlist; PathVertex *pth_vertex, *adj_vertex; ListElmt *element, *member; int found, i; /*PairHeap H; Position *P; */ /*Heap *H; */ /* A_weights binary heap, used for priority queue */ /*double *A_weights; */ /* array of weights to be min-heapified */ CoordData Index2Coord[(gw*gh*2)+1]; int Coord2Index[gw][gh][2]; int index; AdjList *Coord2Vertex[gw][gh][2]; /***************************************************************************** * * * Initialize all of the vertices in the graph. * * * *****************************************************************************/ found = 0; index = 1; for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { pth_vertex = ((AdjList *)list_data(element))->vertex; if (match(pth_vertex, start)) { short int x,y,z; /*********************************************************************** * * * Initialize the start vertex. * * * ***********************************************************************/ x = ((CoordData*)((PathVertex*)pth_vertex)->data)->x; y = ((CoordData*)((PathVertex*)pth_vertex)->data)->y; z = ((CoordData*)((PathVertex*)pth_vertex)->data)->z; Coord2Vertex[x][y][z] = list_data(element); pth_vertex->color = white; pth_vertex->d = 0; pth_vertex->parent = NULL; found = 1; A_weights[index] = pth_vertex->d; Coord2Index[x][y][z] = index; Index2Coord[index].x = x; Index2Coord[index].y = y; Index2Coord[index].z = z; index++; } else { short int x,y,z; /*********************************************************************** * * * Initialize vertices other than the start vertex. * * * ***********************************************************************/ x = ((CoordData*)((PathVertex*)pth_vertex)->data)->x; y = ((CoordData*)((PathVertex*)pth_vertex)->data)->y; z = ((CoordData*)((PathVertex*)pth_vertex)->data)->z; Coord2Vertex[x][y][z] = list_data(element); pth_vertex->color = white; pth_vertex->d = DBL_MAX; pth_vertex->parent = NULL; A_weights[index] = pth_vertex->d; Coord2Index[x][y][z] = index; Index2Coord[index].x = x; Index2Coord[index].y = y; Index2Coord[index].z = z; index++; } } /***************************************************************************** * * * Return if the start vertex was not found. * * * *****************************************************************************/ if (!found) return -1; binheap_build(H,A_weights,gw*gh*2); /* build the heap */ /***************************************************************************** * * * Use Dijkstra's algorithm to compute shortest paths from the start vertex. * * * *****************************************************************************/ i = 0; while (i < graph_vcount(graph)) { short int x,y,z; /************************************************************************** * * * Select the white vertex with the smallest shortest-path estimate. * * * **************************************************************************/ index = binheap_indexofmin(H); /* get index of minimum-weight edge */ binheap_extract(H); /* remove it from the heap */ x = Index2Coord[index].x; y = Index2Coord[index].y; z = Index2Coord[index].z; adjlist = Coord2Vertex[x][y][z]; /************************************************************************** * * * Color the selected vertex black. * * * **************************************************************************/ ((PathVertex *)adjlist->vertex)->color = black; /************************************************************************** * * * Traverse each vertex adjacent to the selected vertex. * * * **************************************************************************/ for (member = list_head(&adjlist->adjacent); member != NULL; member = list_next(member)) { short int px,py,pz; adj_vertex = list_data(member); px = ((CoordData*)((PathVertex*)adj_vertex)->data)->x; py = ((CoordData*)((PathVertex*)adj_vertex)->data)->y; pz = ((CoordData*)((PathVertex*)adj_vertex)->data)->z; /*********************************************************************** * * * Find the adjacent vertex in the list of adjacency-list structures. * * * ***********************************************************************/ pth_vertex = ((AdjList*)Coord2Vertex[px][py][pz])->vertex; /***************************************************************** * * * Relax the adjacent vertex in the list of adjacency-list * * structures. * * * *****************************************************************/ if (relax(adjlist->vertex, pth_vertex, adj_vertex->weight)) { /* update pth_vertex->d in FH */ binheap_decrease_key(H, Coord2Index[px][py][pz] , pth_vertex->d); } } /************************************************************************** * * * Prepare to select the next vertex. * * * **************************************************************************/ i++; } /* destroy binary heap */ /*binheap_destroy(H);*/ /*free(A_weights);*/ /***************************************************************************** * * * Load the vertices with their path information into a list. * * * *****************************************************************************/ list_init(paths, NULL); for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element)) { /************************************************************************** * * * Load each black vertex from the list of adjacency-list structures. * * * **************************************************************************/ pth_vertex = ((AdjList *)list_data(element))->vertex; if (pth_vertex->color == black) { if (list_ins_next(paths, list_tail(paths), pth_vertex) != 0) { printf("Problem inserting!\n"); list_destroy(paths); return -1; } } } return 0; }