Exemple #1
0
void _AddBackEdge(graphP theGraph, int ancestor, int descendant)
{
int fwdArc, backArc;

    /* We get the two edge records of the back edge to embed. */

     fwdArc = theGraph->V[ancestor].fwdArcList;
     while (gp_IsArc(theGraph, fwdArc))
     {
          if (theGraph->G[fwdArc].v == descendant)
              break;

          fwdArc = gp_GetNextArc(theGraph, fwdArc);
          if (fwdArc == theGraph->V[ancestor].fwdArcList)
              fwdArc = NIL;
     }

     if (fwdArc == NIL)
         return;

    backArc = gp_GetTwinArc(theGraph, fwdArc);

    /* The forward arc is removed from the fwdArcList of the ancestor. */
    if (theGraph->V[ancestor].fwdArcList == fwdArc)
    {
        if (gp_GetNextArc(theGraph, fwdArc) == fwdArc)
             theGraph->V[ancestor].fwdArcList = NIL;
        else theGraph->V[ancestor].fwdArcList = gp_GetNextArc(theGraph, fwdArc);
    }

    gp_SetNextArc(theGraph, gp_GetPrevArc(theGraph, fwdArc), gp_GetNextArc(theGraph, fwdArc));
    gp_SetPrevArc(theGraph, gp_GetNextArc(theGraph, fwdArc), gp_GetPrevArc(theGraph, fwdArc));

    /* The forward arc is added to the adjacency list of the ancestor. */
    gp_SetPrevArc(theGraph, fwdArc, gp_AdjacencyListEndMark(ancestor));
    gp_SetNextArc(theGraph, fwdArc, gp_GetFirstArc(theGraph, ancestor));
    gp_SetPrevArc(theGraph, gp_GetFirstArc(theGraph, ancestor), fwdArc);
    gp_SetFirstArc(theGraph, ancestor, fwdArc);

    /* The back arc is added to the adjacency list of the descendant. */
    gp_SetPrevArc(theGraph, backArc, gp_AdjacencyListEndMark(descendant));
    gp_SetNextArc(theGraph, backArc, gp_GetFirstArc(theGraph, descendant));
    gp_SetPrevArc(theGraph, gp_GetFirstArc(theGraph, descendant), backArc);
    gp_SetFirstArc(theGraph, descendant, backArc);

    theGraph->G[backArc].v = ancestor;
}
Exemple #2
0
void _AddBackEdge(graphP theGraph, int ancestor, int descendant)
{
    int fwdArc, backArc;

    /* We get the two edge records of the back edge to embed. */

    fwdArc = gp_GetVertexFwdArcList(theGraph, ancestor);
    while (gp_IsArc(fwdArc))
    {
        if (gp_GetNeighbor(theGraph, fwdArc) == descendant)
            break;

        fwdArc = gp_GetNextArc(theGraph, fwdArc);
        if (fwdArc == gp_GetVertexFwdArcList(theGraph, ancestor))
            fwdArc = NIL;
    }

    if (gp_IsNotArc(fwdArc))
        return;

    backArc = gp_GetTwinArc(theGraph, fwdArc);

    /* The forward arc is removed from the fwdArcList of the ancestor. */
    if (gp_GetVertexFwdArcList(theGraph, ancestor) == fwdArc)
    {
        if (gp_GetNextArc(theGraph, fwdArc) == fwdArc)
            gp_SetVertexFwdArcList(theGraph, ancestor, NIL);
        else gp_SetVertexFwdArcList(theGraph, ancestor, gp_GetNextArc(theGraph, fwdArc));
    }

    gp_SetNextArc(theGraph, gp_GetPrevArc(theGraph, fwdArc), gp_GetNextArc(theGraph, fwdArc));
    gp_SetPrevArc(theGraph, gp_GetNextArc(theGraph, fwdArc), gp_GetPrevArc(theGraph, fwdArc));

    /* The forward arc is added to the adjacency list of the ancestor. */
    gp_SetPrevArc(theGraph, fwdArc, NIL);
    gp_SetNextArc(theGraph, fwdArc, gp_GetFirstArc(theGraph, ancestor));
    gp_SetPrevArc(theGraph, gp_GetFirstArc(theGraph, ancestor), fwdArc);
    gp_SetFirstArc(theGraph, ancestor, fwdArc);

    /* The back arc is added to the adjacency list of the descendant. */
    gp_SetPrevArc(theGraph, backArc, NIL);
    gp_SetNextArc(theGraph, backArc, gp_GetFirstArc(theGraph, descendant));
    gp_SetPrevArc(theGraph, gp_GetFirstArc(theGraph, descendant), backArc);
    gp_SetFirstArc(theGraph, descendant, backArc);

    gp_SetNeighbor(theGraph, backArc, ancestor);
}
Exemple #3
0
int  _ReadAdjList(graphP theGraph, FILE *Infile)
{
int N, I, W, ErrorCode, adjList, J;

     if (Infile == NULL) return NOTOK;
     fgetc(Infile);                             /* Skip the N= */
     fgetc(Infile);
     fscanf(Infile, " %d ", &N);                /* Read N */
     if (gp_InitGraph(theGraph, N) != OK)
     {
    	  printf("Failed to init graph");
          return NOTOK;
     }

     // Clear the visited members of the vertices so they can be used
     // during the adjacency list read operation
     for (I=0; I < N; I++)
          theGraph->G[I].visited = 0;

     // Do the adjacency list read operation for each vertex in order
     for (I = 0, ErrorCode = OK; I < N && ErrorCode==OK; I++)
     {
          // Read the vertex number
          fscanf(Infile, "%d", &theGraph->G[I].v);

          // The vertices are expected to be in numeric ascending order
          if (theGraph->G[I].v != I)
        	  return NOTOK;

          // Skip the colon after the vertex number
          fgetc(Infile);

          // If the vertex already has a non-empty adjacency list, then it is
          // the result of adding edges during processing of preceding vertices.
          // The list is removed from the current vertex I and saved for use
          // during the read operation for I.  Adjacencies to preceding vertices
          // are pulled from this list, if present, or added as directed edges
          // if not.  Adjacencies to succeeding vertices are added as undirected
          // edges, and will be corrected later if the succeeding vertex does not
          // have the matching adjacency using the following mechanism.  After the
          // read operation for a vertex I, any adjacency nodes left in the saved
          // list are converted to directed edges from the preceding vertex to I.
          adjList = gp_GetFirstArc(theGraph, I);
          if (gp_IsArc(theGraph, adjList))
          {
        	  // Store the adjacency node location in the visited member of each
        	  // of the preceding vertices to which I is adjacent so that we can
        	  // efficiently detect the adjacency during the read operation and
        	  // efficiently find the adjacency node.
        	  J = gp_GetFirstArc(theGraph, I);
			  while (gp_IsArc(theGraph, J))
			  {
				  theGraph->G[theGraph->G[J].v].visited = J;
				  J = gp_GetNextArc(theGraph, J);
			  }

        	  // Make the adjacency list circular, for later ease of processing
			  gp_SetPrevArc(theGraph, adjList, gp_GetLastArc(theGraph, I));
			  gp_SetNextArc(theGraph, gp_GetLastArc(theGraph, I), adjList);

        	  // Remove the list from the vertex
			  gp_SetFirstArc(theGraph, I, gp_AdjacencyListEndMark(I));
			  gp_SetLastArc(theGraph, I, gp_AdjacencyListEndMark(I));
          }

          // Read the adjacency list.
          while (1)
          {
        	 // Read the next adjacent vertex, with NIL indicating the list end
             fscanf(Infile, " %d ", &W);
             if (W < 0) break;

             // Vertex numbers must be less than N
             if (W >= N)
                  ErrorCode = NOTOK;

             // Loop edges are not supported, but no reason to throw an error if they occur
             // If a loop occurs, we just do like the ostrich and ignore it
             else if (W == I)
            	 ErrorCode = OK;

             // If the adjacency is to a succeeding, higher numbered vertex,
             // then we'll add an undirected edge for now
             else if (I < W)
             {
             	 ErrorCode = gp_AddEdge(theGraph, I, 0, W, 0);
             }

             // If the adjacency is to a preceding, lower numbered vertex, then
             // we have to pull the adjacency node from the preexisting adjList,
             // if it is there, and if not then we have to add a directed edge.
             else
             {
            	 // If the adjacency node (arc) already exists, then we add it
            	 // as the new first arc of the vertex and delete it from adjList
            	 if (theGraph->G[W].visited)
            	 {
            		 J = theGraph->G[W].visited;

            		 // Remove the arc J from the adjList construct
            		 theGraph->G[W].visited = 0;
            		 if (adjList == J)
            		 {
            			 if ((adjList = gp_GetNextArc(theGraph, J)) == J)
            				 adjList = NIL;
            		 }
            		 gp_SetPrevArc(theGraph, gp_GetNextArc(theGraph, J), gp_GetPrevArc(theGraph, J));
            		 gp_SetNextArc(theGraph, gp_GetPrevArc(theGraph, J), gp_GetNextArc(theGraph, J));

            		 gp_AttachFirstArc(theGraph, I, J);
            	 }

            	 // If an adjacency node to the lower numbered vertex W does not
            	 // already exist, then we make a new directed arc from the current
            	 // vertex I to W.
            	 else
            	 {
            		 // It is added as the new first arc in both vertices
                	 ErrorCode = gp_AddEdge(theGraph, I, 0, W, 0);
                	 if (ErrorCode == OK)
                		 // Note that this call also sets OUTONLY on the twin arc
                		 gp_SetDirection(theGraph, gp_GetFirstArc(theGraph, W), EDGEFLAG_DIRECTION_INONLY);
            	 }
             }

             if (ErrorCode != OK) break;
          }

          // If there are still adjList entries after the read operation
          // then those entries are not representative of full undirected edges.
          // Rather, they represent incoming directed arcs from other vertices
          // into vertex I. They need to be added back into I's adjacency list but
          // marked as "INONLY", while the twin is marked "OUTONLY" (by the same function).
          while (gp_IsArc(theGraph, adjList))
          {
        	  J = adjList;

			  theGraph->G[theGraph->G[J].v].visited = 0;

 			  if ((adjList = gp_GetNextArc(theGraph, J)) == J)
 				  adjList = NIL;

     		  gp_SetPrevArc(theGraph, gp_GetNextArc(theGraph, J), gp_GetPrevArc(theGraph, J));
     		  gp_SetNextArc(theGraph, gp_GetPrevArc(theGraph, J), gp_GetNextArc(theGraph, J));

     		  gp_AttachFirstArc(theGraph, I, J);
     		  gp_SetDirection(theGraph, J, EDGEFLAG_DIRECTION_INONLY);
          }
     }

     return ErrorCode;
}