lib/dgRange.c File Reference

#include "common.h"
#include "diGraph.h"

Include dependency graph for dgRange.c:

Go to the source code of this file.

Data Structures

struct  bfEdge
struct  bfVertex
struct  bfGraph
struct  bfRange

Functions

static void bfGraphFree (struct bfGraph **pGraph)
static struct bfGraphbfGraphFromRangeGraph (struct diGraph *rangeGraph, boolean(*findEdgeRange)(struct dgEdge *edge, int *retMin, int *retMax), struct dgNode *a, struct dgNode *b, int abMin, int abMax)
static boolean bfCheckGraph (struct bfGraph *graph)
boolean dgAddedRangeConsistent (struct diGraph *rangeGraph, struct dgNode *a, struct dgNode *b, int abMin, int abMax, boolean(*findEdgeRange)(struct dgEdge *edge, int *retMin, int *retMax))
boolean dgRangesConsistent (struct diGraph *rangeGraph, boolean(*findEdgeRange)(struct dgEdge *edge, int *retMin, int *retMax))

Variables

static char const rcsid [] = "$Id: dgRange.c,v 1.3 2003/05/06 07:33:42 kate Exp $"


Function Documentation

static boolean bfCheckGraph ( struct bfGraph graph  )  [static]

Definition at line 163 of file dgRange.c.

References bfGraph::edgeCount, bfGraph::edges, FALSE, bfEdge::in, bfVertex::position, TRUE, bfGraph::vertexCount, and bfGraph::vertices.

Referenced by dgAddedRangeConsistent().

00165 {
00166 struct bfVertex *vertices = graph->vertices, *in, *out;
00167 int vertexCount = graph->vertexCount;
00168 int edgeCount = graph->edgeCount;
00169 struct bfEdge *edges = graph->edges, *edge;
00170 int i, edgeIx;
00171 int maxIterations = vertexCount - 1;
00172 boolean anyChange = FALSE;
00173 int newPos;
00174 
00175 for (i=0; i<vertexCount; ++i)
00176     vertices[i].position = 0x3fffffff;    /* Mighty big number. */
00177 for (i=0; i<maxIterations; ++i)
00178     {
00179     anyChange = FALSE;
00180     for (edgeIx = 0, edge = edges; edgeIx < edgeCount; ++edgeIx, ++edge)
00181         {
00182         in = edge->in;
00183         out = edge->out;
00184         newPos = in->position + edge->distance;
00185         if (newPos < out->position)
00186             {
00187             out->position = newPos;
00188             anyChange = TRUE;
00189             }
00190         }
00191     if (!anyChange)
00192         break;
00193     }
00194 return !anyChange;
00195 }

Here is the caller graph for this function:

static void bfGraphFree ( struct bfGraph **  pGraph  )  [static]

Definition at line 41 of file dgRange.c.

References bfGraph::edges, freeMem(), freez(), and bfGraph::vertices.

Referenced by dgAddedRangeConsistent().

00043 {
00044 struct bfGraph *graph = *pGraph;
00045 if (graph != NULL)
00046     {
00047     freeMem(graph->vertices);
00048     freeMem(graph->edges);
00049     freez(pGraph);
00050     }
00051 }

Here is the call graph for this function:

Here is the caller graph for this function:

static struct bfGraph* bfGraphFromRangeGraph ( struct diGraph rangeGraph,
boolean(*)(struct dgEdge *edge, int *retMin, int *retMax)  findEdgeRange,
struct dgNode a,
struct dgNode b,
int  abMin,
int  abMax 
) [static, read]

Definition at line 53 of file dgRange.c.

References AllocArray, AllocVar, dlCount(), bfGraph::edgeCount, diGraph::edgeList, dgConnection::edgeOnList, bfGraph::edges, newEdge(), dgConnection::next, dgNode::next, dgNode::nextList, dgConnection::node, diGraph::nodeList, slAddHead, dgNode::topoOrder, dlNode::val, bfGraph::vertexCount, bfGraph::vertices, and bfVertex::waysOut.

Referenced by dgAddedRangeConsistent().

00058                          :
00059  *     sourceNode destNode minDistance maxDistance
00060  *    -------------------------------------------
00061  *         A         B         2          5
00062  * The bfGraph would have:
00063  *     sourceNode destNode   edgeVal  meaning
00064  *    --------------------------------------------
00065  *         A         B         5     D(A) - D(B) <= 5 
00066  *         B         A        -2     D(B) - D(A) <= -2
00067  * Furthermore the bfGraph introduces a new node,
00068  * "zero", which has a zero-valued connection to
00069  * all other nodes.
00070  *
00071  * This graph can then be processed via the Bellman-
00072  * Ford algorithm (see p. 532 of Cormen,Leiserson and
00073  * Rivest's Introduction to Algorithms, MIT Press 1990)
00074  * to see if the bfGraph, and by extension the range
00075  * graph, is consistent.
00076  */
00077 {
00078 struct bfGraph *bfGraph;
00079 struct bfVertex *vertices, *freeVertex, *newSource, *newDest, *zeroVertex;
00080 struct bfEdge *edges, *newEdge, *freeEdge;
00081 struct dgNode *oldSource, *oldDest, *oldNode;
00082 int oldEdgeCount = dlCount(rangeGraph->edgeList);
00083 int oldVertexCount = 0;
00084 
00085 /* Coopt topoOrder field to store unique ID for each
00086  * node, starting at 1.  (We'll reserve 0 for the
00087  * node we insert - the Belman Ford "zero" node.)*/
00088 for (oldNode = rangeGraph->nodeList; oldNode != NULL; oldNode = oldNode->next)
00089     oldNode->topoOrder = ++oldVertexCount;
00090 
00091 /* Allocate space for new graph. */
00092 AllocVar(bfGraph);
00093 bfGraph->vertexCount = oldVertexCount + 1;
00094 bfGraph->vertices = freeVertex = AllocArray(vertices, bfGraph->vertexCount);
00095 bfGraph->edgeCount = 2*oldEdgeCount + oldVertexCount;
00096 if (a != NULL)
00097   bfGraph->edgeCount += 2;
00098 bfGraph->edges = freeEdge = AllocArray(edges, bfGraph->edgeCount);
00099 
00100 /* Get zero vertex. */
00101 zeroVertex = freeVertex++;
00102 
00103 /* Scan through old graph and add vertices to new graph. */
00104 for (oldSource = rangeGraph->nodeList; oldSource != NULL; 
00105     oldSource = oldSource->next)
00106     {
00107     struct dgConnection *dgConn;
00108     int rangeMin, rangeMax;
00109 
00110     /* Allocate new source vertex. */
00111     newSource = freeVertex++;
00112 
00113     /* Make connection from zero vertex to this one. */
00114     newEdge = freeEdge++;
00115     newEdge->distance = 0;
00116     newEdge->in = zeroVertex;
00117     newEdge->out = newSource;
00118     slAddHead(&zeroVertex->waysOut, newEdge);
00119 
00120     /* Loop through all ways out of source. */
00121     for (dgConn = oldSource->nextList; dgConn != NULL; dgConn = dgConn->next)
00122         {
00123         /* Find destination vertex and size range of edge. */
00124         if ((*findEdgeRange)(dgConn->edgeOnList->val, &rangeMin, &rangeMax))
00125             {
00126             oldDest = dgConn->node;
00127             newDest = &vertices[oldDest->topoOrder];
00128 
00129             /* Make two new edges corresponding to old edge. */
00130             newEdge = freeEdge++;
00131             newEdge->distance = rangeMax;
00132             newEdge->in = newSource;
00133             newEdge->out = newDest;
00134             slAddHead(&newSource->waysOut, newEdge);
00135             newEdge = freeEdge++;
00136             newEdge->distance = -rangeMin;
00137             newEdge->in = newDest;
00138             newEdge->out = newSource;
00139             slAddHead(&newDest->waysOut, newEdge);
00140             }
00141         }
00142     }
00143 /* Add additional pair of edges for extra range if applicable. */
00144 if (a != NULL)
00145     {
00146     newSource = &vertices[a->topoOrder];
00147     newDest = &vertices[b->topoOrder];
00148     newEdge = freeEdge++;
00149     newEdge->distance = abMax;
00150     newEdge->in = newSource;
00151     newEdge->out = newDest;
00152     slAddHead(&newSource->waysOut, newEdge);
00153     newEdge = freeEdge++;
00154     newEdge->distance = -abMin;
00155     newEdge->in = newDest;
00156     newEdge->out = newSource;
00157     slAddHead(&newDest->waysOut, newEdge);
00158     }
00159 bfGraph->edgeCount = freeEdge - bfGraph->edges;
00160 return bfGraph;
00161 }

Here is the call graph for this function:

Here is the caller graph for this function:

boolean dgAddedRangeConsistent ( struct diGraph rangeGraph,
struct dgNode a,
struct dgNode b,
int  abMin,
int  abMax,
boolean(*)(struct dgEdge *edge, int *retMin, int *retMax)  findEdgeRange 
)

Definition at line 197 of file dgRange.c.

References bfCheckGraph(), bfGraphFree(), and bfGraphFromRangeGraph().

Referenced by dgRangesConsistent().

00203 {
00204 struct bfGraph *bfGraph;
00205 boolean ok; 
00206 
00207 bfGraph = bfGraphFromRangeGraph(rangeGraph, findEdgeRange, a, b, abMin, abMax);
00208 ok = bfCheckGraph(bfGraph);
00209 bfGraphFree(&bfGraph);
00210 return ok;
00211 }

Here is the call graph for this function:

Here is the caller graph for this function:

boolean dgRangesConsistent ( struct diGraph rangeGraph,
boolean(*)(struct dgEdge *edge, int *retMin, int *retMax)  findEdgeRange 
)

Definition at line 213 of file dgRange.c.

References dgAddedRangeConsistent().

00217 {
00218 return dgAddedRangeConsistent(rangeGraph, NULL, NULL, 0, 0, findEdgeRange);
00219 }

Here is the call graph for this function:


Variable Documentation

char const rcsid[] = "$Id: dgRange.c,v 1.3 2003/05/06 07:33:42 kate Exp $" [static]

Definition at line 8 of file dgRange.c.


Generated on Tue Dec 25 19:42:54 2007 for blat by  doxygen 1.5.2