int main () { int i, data; int v_id[V_COUNT]; DfsVertex *dfs_vs[V_COUNT]; Graph graph; DfsVertex *dfs_vertex; List ordered; ListElmt *element; graph_init (&graph, &match, NULL); for (i = 0; i < V_COUNT; i++) { v_id[i] = i; if ((dfs_vertex = (DfsVertex *) malloc (sizeof(DfsVertex))) == NULL) return -1; dfs_vertex->data = &v_id[i]; dfs_vertex->color = white; dfs_vs[i] = dfs_vertex; graph_ins_vertex (&graph, (void *) dfs_vertex); /* printf ("vertex[%d] addr=%d\n", i, (void *) &vertex[i]); */ } printf ("graph vcount=%d\n", graph_vcount (&graph)); /* Graph as in figure 11.8 Network hops. */ /* graph_ins_edge (&graph, (void *) dfs_vs[0], (void *) dfs_vs[1]); */ graph_ins_edge (&graph, (void *) dfs_vs[0], (void *) dfs_vs[2]); graph_ins_edge (&graph, (void *) dfs_vs[2], (void *) dfs_vs[1]); graph_ins_edge (&graph, (void *) dfs_vs[1], (void *) dfs_vs[3]); /* graph_ins_edge (&graph, (void *) dfs_vs[2], (void *) dfs_vs[4]); */ graph_ins_edge (&graph, (void *) dfs_vs[3], (void *) dfs_vs[4]); graph_ins_edge (&graph, (void *) dfs_vs[4], (void *) dfs_vs[5]); graph_ins_edge (&graph, (void *) dfs_vs[1], (void *) dfs_vs[6]); printf ("graph ecount=%d\n", graph_ecount (&graph)); dfs (&graph, &ordered); printf ("size of ordered list=%d\n", list_size (&ordered)); for (element = list_head (&ordered); element != NULL; element = list_next (element)) { dfs_vertex = (list_data (element)); printf ("vertex id=%d,\tcolour=%d\n", *(int *) dfs_vertex->data, (int) dfs_vertex->color); } list_destroy (&ordered); graph_destroy (&graph); 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; }
/* 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 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; }