|
Graphviz
2.29.20120523.0446
|
00001 /* $Id$ $Revision$ */ 00002 /* vim:set shiftwidth=4 ts=8: */ 00003 00004 /************************************************************************* 00005 * Copyright (c) 2011 AT&T Intellectual Property 00006 * All rights reserved. This program and the accompanying materials 00007 * are made available under the terms of the Eclipse Public License v1.0 00008 * which accompanies this distribution, and is available at 00009 * http://www.eclipse.org/legal/epl-v10.html 00010 * 00011 * Contributors: See CVS logs. Details at http://www.graphviz.org/ 00012 *************************************************************************/ 00013 00014 00015 /****************************************** 00016 00017 Breadth First Search 00018 Computes single-source distances for 00019 unweighted graphs 00020 00021 ******************************************/ 00022 00023 #include "bfs.h" 00024 #include <stdlib.h> 00025 /* #include <math.h> */ 00026 00027 void bfs(int vertex, vtx_data * graph, int n, DistType * dist, Queue * Q) 00028 /* compute vector 'dist' of distances of all nodes from 'vertex' */ 00029 { 00030 int i; 00031 int closestVertex, neighbor; 00032 DistType closestDist = INT_MAX; 00033 00034 /* initial distances with edge weights: */ 00035 for (i = 0; i < n; i++) 00036 dist[i] = -1; 00037 dist[vertex] = 0; 00038 00039 initQueue(Q, vertex); 00040 00041 if (graph[0].ewgts == NULL) { 00042 while (deQueue(Q, &closestVertex)) { 00043 closestDist = dist[closestVertex]; 00044 for (i = 1; i < graph[closestVertex].nedges; i++) { 00045 neighbor = graph[closestVertex].edges[i]; 00046 if (dist[neighbor] < -0.5) { /* first time to reach neighbor */ 00047 dist[neighbor] = closestDist + 1; 00048 enQueue(Q, neighbor); 00049 } 00050 } 00051 } 00052 } else { 00053 while (deQueue(Q, &closestVertex)) { 00054 closestDist = dist[closestVertex]; 00055 for (i = 1; i < graph[closestVertex].nedges; i++) { 00056 neighbor = graph[closestVertex].edges[i]; 00057 if (dist[neighbor] < -0.5) { /* first time to reach neighbor */ 00058 dist[neighbor] = 00059 closestDist + 00060 (DistType) graph[closestVertex].ewgts[i]; 00061 enQueue(Q, neighbor); 00062 } 00063 } 00064 } 00065 } 00066 00067 /* For dealing with disconnected graphs: */ 00068 for (i = 0; i < n; i++) 00069 if (dist[i] < -0.5) /* 'i' is not connected to 'vertex' */ 00070 dist[i] = closestDist + 10; 00071 } 00072 00073 int 00074 bfs_bounded(int vertex, vtx_data * graph, int n, DistType * dist, 00075 Queue * Q, int bound, int *visited_nodes) 00076 /* compute vector 'dist' of distances of all nodes from 'vertex' */ 00077 /* ignore nodes whose distance to 'vertex' is more than bound */ 00078 { 00079 /* we assume here, that all distances are initialized with -1 !!!! */ 00080 00081 int i; 00082 int num_visit; 00083 int closestVertex, neighbor; 00084 DistType closestDist; 00085 /* initialize distances with edge weights: */ 00086 /* for (i=0; i<n; i++) */ 00087 /* dist[i]=-1; */ 00088 00089 dist[vertex] = 0; 00090 00091 initQueue(Q, vertex); 00092 00093 num_visit = 0; 00094 while (deQueue(Q, &closestVertex)) { 00095 closestDist = dist[closestVertex]; 00096 if (closestDist > bound) { 00097 dist[closestVertex] = -1; 00098 break; 00099 } else { 00100 visited_nodes[num_visit++] = closestVertex; 00101 } 00102 for (i = 1; i < graph[closestVertex].nedges; i++) { 00103 neighbor = graph[closestVertex].edges[i]; 00104 if (dist[neighbor] < -0.5) { /* first time to reach neighbor */ 00105 dist[neighbor] = closestDist + 1; 00106 enQueue(Q, neighbor); 00107 } 00108 } 00109 } 00110 00111 /* set distances of all nodes in Queue to -1 */ 00112 /* for next run */ 00113 while (deQueue(Q, &closestVertex)) { 00114 dist[closestVertex] = -1; 00115 } 00116 dist[vertex] = -1; 00117 return num_visit; 00118 } 00119 00120 #ifndef __cplusplus 00121 00122 void mkQueue(Queue * qp, int size) 00123 { 00124 qp->data = N_GNEW(size, int); 00125 qp->queueSize = size; 00126 qp->start = qp->end = 0; 00127 } 00128 00129 Queue *newQueue(int size) 00130 { 00131 Queue *qp = GNEW(Queue); 00132 mkQueue(qp, size); 00133 return qp; 00134 } 00135 00136 void freeQueue(Queue * qp) 00137 { 00138 free(qp->data); 00139 } 00140 00141 void delQueue(Queue * qp) 00142 { 00143 free(qp->data); 00144 free(qp); 00145 } 00146 00147 void initQueue(Queue * qp, int startVertex) 00148 { 00149 qp->data[0] = startVertex; 00150 qp->start = 0; 00151 qp->end = 1; 00152 } 00153 00154 boolean deQueue(Queue * qp, int *vertex) 00155 { 00156 if (qp->start >= qp->end) 00157 return FALSE; /* underflow */ 00158 *vertex = qp->data[qp->start++]; 00159 return TRUE; 00160 } 00161 00162 boolean enQueue(Queue * qp, int vertex) 00163 { 00164 if (qp->end >= qp->queueSize) 00165 return FALSE; /* overflow */ 00166 qp->data[qp->end++] = vertex; 00167 return TRUE; 00168 } 00169 00170 #endif
1.7.5