Graphviz  2.29.20120523.0446
lib/neatogen/bfs.c
Go to the documentation of this file.
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